Re: performance: using mlock(2) on httpd parent process

2002-03-20 Thread Stas Bekman

Hi Scott,

 On Wed, 20 Mar 2002, Stas Bekman wrote:
 
mod_perl child processes save a lot of memory when they can share memory
with the parent process and quite often we get reports from people that
they lose that shared memory when the system decides to page out the
parent's memory pages because they are LRU (least recently used, the
algorithm used by many memory managers).

 
 I'm fairly certain that this is not an issue.  If a page was shared COW
 before being paged out, I expect it will be shared COW when paged back in,
 at least for any modern OS.

But if the system needs to page things out, most of the parent process's 
  pages will be scheduled to go first, no? So we are talking about a 
constant page-in/page-out from/to the parent process as a performance 
degradation rather than memory unsharing. Am I correct?

 [To verify that I wasn't talking through my hat, here, I just verified
 this using RedHat 7.2 running kernel 2.4.9-21.  If you're interested in my
 methodology, drop me an email.]

I suppose that this could vary from one kernel version to another.

I'm just repeating the reports posted to the mod_perl list. I've never 
seen such a problem myself, since I try hard to have close to zero swap 
usage.

[Yes, please let me know your methodology for testing this]

I believe that this applies to all httpd modules and httpd itself, the
more we can share the less memory resources are needed, and usually it
leads to a better performance.

 
 I'm absolutely _certain_ that unmodified pages from executable files will
 be backed by the executable, and will thus be shared by default.
 
 
Therefore my question is there any reason for not using mlockall(2) in
the parent process on systems that support it and when the parent httpd
is started as root (mlock* works only within root owned processes).

 
 I don't think mlockall is appropriate for something with the heft of
 mod_perl.
 
 Why are the pages being swapped out in the first place?  Presumably
 there's a valid reason. 

Well, the system coming close to zero of real memory available. The 
parent process starts swapping like crazy because most of its pages are 
LRU, slowing the whole system down and if the load doesn't go away, the 
system takes a whirl down to a halt.

 Doing mlockall on your mod_perl would result in
 restricting the memory available to the rest of the system.  Whatever is
 causing mod_perl to page out would then start thrashing.  Worse, since
 mlockall will lock down mod_perl pages indiscriminately, the resulting
 thrashing will probably be even worse than what they're seeing right now.

Possible, I've never tried this myself and therefore asked. Someone has
suggested using P_SYSTEM flag which is supposed to tell the system not to
page out certain pages, but seems to be a *BSD thingy. I've also seen

   madvise(2) - give advice about use of memory

but again no personal experience here.


_
Stas Bekman JAm_pH  --   Just Another mod_perl Hacker
http://stason.org/  mod_perl Guide   http://perl.apache.org/guide
mailto:[EMAIL PROTECTED]  http://ticketmaster.com http://apacheweek.com
http://singlesheaven.com http://perl.apache.org http://perlmonth.com/




Re: performance: using mlock(2) on httpd parent process

2002-03-20 Thread Aaron Bannert

On Thu, Mar 21, 2002 at 02:14:04AM +0800, Stas Bekman wrote:
 But if the system needs to page things out, most of the parent process's 
  pages will be scheduled to go first, no? So we are talking about a 
 constant page-in/page-out from/to the parent process as a performance 
 degradation rather than memory unsharing. Am I correct?
[...]
 Well, the system coming close to zero of real memory available. The 
 parent process starts swapping like crazy because most of its pages are 
 LRU, slowing the whole system down and if the load doesn't go away, the 
 system takes a whirl down to a halt.

FWIW, Solaris 8 introduced priority paging, which basicly means
that pages that are non-executable will be swapped out earlier than
higher-priority executable pages. This of course introduces nasty little
tricks like marking a data file as executable just to ensure that it
gets priority paging.

I'm not sure how this affects mod_perl and it's data is runtime-compiled
bytecode situation, but it means that we get it for free w/ httpd and
all its dependent libraries (and DSOs).

-aaron

p.s. It can be enabled on Solaris 7, it's just not on by default.




Re: performance: using mlock(2) on httpd parent process

2002-03-20 Thread Ian Holsman

Aaron Bannert wrote:
 On Thu, Mar 21, 2002 at 02:14:04AM +0800, Stas Bekman wrote:
 
But if the system needs to page things out, most of the parent process's 
 pages will be scheduled to go first, no? So we are talking about a 
constant page-in/page-out from/to the parent process as a performance 
degradation rather than memory unsharing. Am I correct?
 
 [...]
 
Well, the system coming close to zero of real memory available. The 
parent process starts swapping like crazy because most of its pages are 
LRU, slowing the whole system down and if the load doesn't go away, the 
system takes a whirl down to a halt.
 
 
 FWIW, Solaris 8 introduced priority paging, which basicly means
 that pages that are non-executable will be swapped out earlier than
 higher-priority executable pages. This of course introduces nasty little
 tricks like marking a data file as executable just to ensure that it
 gets priority paging.

priority paging is more to do with the filesystem cache than anything 
else. in low memory conditions it start freeing pages used by the file 
cache first. without it you could swap your machine to death by copying
a 1 gig file around the place.


 
 I'm not sure how this affects mod_perl and it's data is runtime-compiled
 bytecode situation, but it means that we get it for free w/ httpd and
 all its dependent libraries (and DSOs).
 
 -aaron
 
 p.s. It can be enabled on Solaris 7, it's just not on by default.
 






Re: performance: using mlock(2) on httpd parent process

2002-03-20 Thread Aaron Bannert

On Wed, Mar 20, 2002 at 11:19:44AM -0800, Ian Holsman wrote:
 FWIW, Solaris 8 introduced priority paging, which basicly means
 that pages that are non-executable will be swapped out earlier than
 higher-priority executable pages. This of course introduces nasty little
 tricks like marking a data file as executable just to ensure that it
 gets priority paging.
 
 priority paging is more to do with the filesystem cache than anything 
 else. in low memory conditions it start freeing pages used by the file 
 cache first. without it you could swap your machine to death by copying
 a 1 gig file around the place.

We are talking about a low memory condition, when the scanner is looking
for a page to swap out for whatever reason (including filesystem
activity). Before priority paging it would select a LRU page, which
could very likely be the program that is triggering the page fault.
With priority paging enabled, a non-executable page will be selected for
swapping before an executable one. Therefore the httpd binary will remain
in hard-wired memory longer than the anonymous pages it is operating on
(including the COW pages inherited in the children and any filesystem
cache pages).

Without priority paging an httpd process that required access to more
memory than physically present on the system could potentially cause
itself to be paged out and then immediate back in as soon as the next
instruction tripped a page fault. This would result in a huge amount
of thrashing, for even something as simple as copying a file (as
with your example).

So my point is we don't have to do mlock() on solaris8 (or 7 with p.p.
enabled) since we get similiar or sufficient behavior already.

-aaron




Re: performance: using mlock(2) on httpd parent process

2002-03-20 Thread Stas Bekman

Scott Hess wrote:
 On Thu, 21 Mar 2002, Stas Bekman wrote:
 
On Wed, 20 Mar 2002, Stas Bekman wrote:


mod_perl child processes save a lot of memory when they can share 
memory with the parent process and quite often we get reports from 
people that they lose that shared memory when the system decides to 
page out the parent's memory pages because they are LRU (least 
recently used, the algorithm used by many memory managers).


I'm fairly certain that this is not an issue.  If a page was shared 
COW before being paged out, I expect it will be shared COW when paged 
back in, at least for any modern OS.

But if the system needs to page things out, most of the parent process's
pages will be scheduled to go first, no? So we are talking about a
constant page-in/page-out from/to the parent process as a performance
degradation rather than memory unsharing. Am I correct?

 
 The system is going to page out an approximation of the
 least-recently-used pages.  If the children are using those pages, then
 they won't be paged out, regardless of what the parent is doing.  [If the
 children _aren't_ using those pages, then who cares?]

mod_perl users do care. let's say you've preloaded a bunch of modules 
which aren't in use now but may be used any moment. Ideally we don't 
want any of the pages to be swapped out. Of course this is all possible 
if the demand does go over the supply.

I'm just repeating the reports posted to the mod_perl list. I've never
seen such a problem myself, since I try hard to have close to zero swap
usage.

 
 :-).  In my experience, you can get some really weird stuff happening when
 you start swapping mod_perl.  It seems to be stable in memory usage,
 though, so long as you have MaxClients set low enough that your maximum
 amount of committed memory is appropriate.  Also, I've seen people run
 other heavyweight processes, like mysql, on the same system, so that when
 the volume spikes, mod_perl spikes AND mysql spikes.  A sure recipe for
 disaster.

Well, we (mod_perl users) use tools like Apache::GTopLimit and 
Apache::SizeLimit which monitor the child process' memory and will kill 
the process after a request if the memory size crossed a total memory 
used limit, or lost too much of a shared memory. I think that's where 
the problem lays, the memory usage tools report that the sharing went 
down and the process gets killed when the parent's pages are getting 
paged out. Even if in reality the sharing is still there. The memory 
reporting tools don't reflect the reality.


[Yes, please let me know your methodology for testing this]

 
 OK, two programs.  bigshare.c:

thanks Scott, I've forwarded this code to the folks who are having the 
trouble with. and it'll stay in the archives for others to re-use.


Therefore my question is there any reason for not using mlockall(2) in
the parent process on systems that support it and when the parent 
httpd is started as root (mlock* works only within root owned 
processes).

I don't think mlockall is appropriate for something with the heft of
mod_perl.

Why are the pages being swapped out in the first place?  Presumably
there's a valid reason. 

Well, the system coming close to zero of real memory available. The
parent process starts swapping like crazy because most of its pages are
LRU, slowing the whole system down and if the load doesn't go away, the
system takes a whirl down to a halt.

 
 I can think of a couple possible causes.  One is the MaxClients setting.  
 Say you have MaxClients set to 50, but on a standard day you never need 
 more than 15 servers.  Then you get listed on slashdot.  As you pass, oh, 
 30 simultaneous servers, you start thrashing, so requests take longer to 
 process, so you immediately spike to your MaxClients of 50 and the server 
 goes right down the drain.  If you shut things down and start them back 
 up, it's likely you'll immediately spike to 50 again, and back down the 
 drain it goes.
 
 I've found that it's _super_ important to make certain you've pushed
 mod_perl to MaxClients under your standard conditions.  Once you start
 swapping, you're doomed, unless the traffic was a very short spike.
 
 Another possible cause is that you have another heavyweight server running
 on the same server.  As I indicated above, I've seen people do this with
 things like mysql.  Since high mod_perl traffic implies high mysql
 traffic, it's just like having MaxClients set too high, but twice as bad!
 
 Another possible cause is that the OS is aggressively grabbing pages for
 the filesystem cache.  It's possible that tuning down the size of the
 filesystem cache would be appropriate - many webservers have a very large
 maximum amount of data they might server, but a very small working set.
 
 Really, though, all of this really tends to come down to MaxClients.  The
 database load is proportional to the number of clients, the filesystem
 load is proportional to the number of clients, everything is proportional
 to the number of 

Re: performance: using mlock(2) on httpd parent process

2002-03-20 Thread Scott Hess

On Wed, 20 Mar 2002, Stas Bekman wrote:
 mod_perl child processes save a lot of memory when they can share memory
 with the parent process and quite often we get reports from people that
 they lose that shared memory when the system decides to page out the
 parent's memory pages because they are LRU (least recently used, the
 algorithm used by many memory managers).

I'm fairly certain that this is not an issue.  If a page was shared COW
before being paged out, I expect it will be shared COW when paged back in,
at least for any modern OS.

[To verify that I wasn't talking through my hat, here, I just verified
this using RedHat 7.2 running kernel 2.4.9-21.  If you're interested in my
methodology, drop me an email.]

 I believe that this applies to all httpd modules and httpd itself, the
 more we can share the less memory resources are needed, and usually it
 leads to a better performance.

I'm absolutely _certain_ that unmodified pages from executable files will
be backed by the executable, and will thus be shared by default.

 Therefore my question is there any reason for not using mlockall(2) in
 the parent process on systems that support it and when the parent httpd
 is started as root (mlock* works only within root owned processes).

I don't think mlockall is appropriate for something with the heft of
mod_perl.

Why are the pages being swapped out in the first place?  Presumably
there's a valid reason.  Doing mlockall on your mod_perl would result in
restricting the memory available to the rest of the system.  Whatever is
causing mod_perl to page out would then start thrashing.  Worse, since
mlockall will lock down mod_perl pages indiscriminately, the resulting
thrashing will probably be even worse than what they're seeing right now.

Later,
scott




performance: using mlock(2) on httpd parent process

2002-03-19 Thread Stas Bekman

mod_perl child processes save a lot of memory when they can share memory 
with the parent process and quite often we get reports from people that 
they lose that shared memory when the system decides to page out the 
parent's memory pages because they are LRU (least recently used, the 
algorithm used by many memory managers). I believe that this applies to 
all httpd modules and httpd itself, the more we can share the less 
memory resources are needed, and usually it leads to a better performance.

Therefore my question is there any reason for not using mlockall(2) in 
the parent process on systems that support it and when the parent httpd 
is started as root (mlock* works only within root owned processes).

Of course this is relevant to 1.3 and 2.0 httpds.

Thanks.
_
Stas Bekman JAm_pH  --   Just Another mod_perl Hacker
http://stason.org/  mod_perl Guide   http://perl.apache.org/guide
mailto:[EMAIL PROTECTED]  http://ticketmaster.com http://apacheweek.com
http://singlesheaven.com http://perl.apache.org http://perlmonth.com/




Re: performance: using mlock(2) on httpd parent process

2002-03-19 Thread Greg Stein

On Wed, Mar 20, 2002 at 12:02:53PM +0800, Stas Bekman wrote:
 mod_perl child processes save a lot of memory when they can share memory 
 with the parent process and quite often we get reports from people that 
 they lose that shared memory when the system decides to page out the 
 parent's memory pages because they are LRU (least recently used, the 
 algorithm used by many memory managers). I believe that this applies to 
 all httpd modules and httpd itself, the more we can share the less 
 memory resources are needed, and usually it leads to a better performance.
 
 Therefore my question is there any reason for not using mlockall(2) in 
 the parent process on systems that support it and when the parent httpd 
 is started as root (mlock* works only within root owned processes).

We don't really support httpd running as root. That is what that whole
BIG_SECURITY_HOLE thing is about.

If somebody is going to run as root, then let them put the mlockall() patch
in themselves. Further, since mlockall() jams everything into memory, I'm
wary of making this the default behavior [when running as root]. In turn,
that means that we'd have to introduce a new directive to turn on the
mlockall thing.

So the net result is: new behavior and a new directive to support a case
(httpd running as root) that we don't even want/like people doing in the
first place.

I'd be a heavy -0 on such a thing.

Cheers,
-g

-- 
Greg Stein, http://www.lyra.org/



Re: performance: using mlock(2) on httpd parent process

2002-03-19 Thread Stas Bekman

Greg Stein wrote:
 On Wed, Mar 20, 2002 at 12:02:53PM +0800, Stas Bekman wrote:
 
mod_perl child processes save a lot of memory when they can share memory 
with the parent process and quite often we get reports from people that 
they lose that shared memory when the system decides to page out the 
parent's memory pages because they are LRU (least recently used, the 
algorithm used by many memory managers). I believe that this applies to 
all httpd modules and httpd itself, the more we can share the less 
memory resources are needed, and usually it leads to a better performance.

Therefore my question is there any reason for not using mlockall(2) in 
the parent process on systems that support it and when the parent httpd 
is started as root (mlock* works only within root owned processes).

 
 We don't really support httpd running as root. That is what that whole
 BIG_SECURITY_HOLE thing is about.

The parent process is always running as root if you want to bind to port 
80. And that's the only process that needs locking with mlockall().

We don't want any locking for child processes.

 If somebody is going to run as root, then let them put the mlockall() patch
 in themselves. Further, since mlockall() jams everything into memory, I'm
 wary of making this the default behavior [when running as root]. In turn,
 that means that we'd have to introduce a new directive to turn on the
 mlockall thing.
 
 So the net result is: new behavior and a new directive to support a case
 (httpd running as root) that we don't even want/like people doing in the
 first place.

If this improves the httpd's performance what's so wrong with adding a 
new directive?

 I'd be a heavy -0 on such a thing.



-- 


_
Stas Bekman JAm_pH  --   Just Another mod_perl Hacker
http://stason.org/  mod_perl Guide   http://perl.apache.org/guide
mailto:[EMAIL PROTECTED]  http://ticketmaster.com http://apacheweek.com
http://singlesheaven.com http://perl.apache.org http://perlmonth.com/