Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 16 Nov 1999 21:06:42 +0100
From:      Poul-Henning Kamp <phk@critter.freebsd.dk>
Subject:   Re: the ps/cmdline caching 
Message-ID:  <26892.942782802.1@critter.freebsd.dk>

next in thread | raw e-mail | index | archive | help
------- =_aaaaaaaaaa
Content-Type: message/rfc822
Content-Description: Original Message

To: core@freebsd.org
Subject: Re: the ps/cmdline caching 
In-reply-to: Your message of "Tue, 16 Nov 1999 11:37:40 MST."
             <199911161837.LAA00345@caspian.plutotech.com> 
Date: Tue, 16 Nov 1999 21:06:42 +0100
Message-ID: <26892.942782802@critter.freebsd.dk>
From: Poul-Henning Kamp <phk@critter.freebsd.dk>
MIME-Version: 1.0

In message <199911161837.LAA00345@caspian.plutotech.com>, "Justin T. Gibbs" wri
tes:

>I must have missed a thread somewhere.  Can I get a reference to what
>this problem is?

Run this on a SMP box and it will die in seconds:

	i=0
	while [ $i -lt 200 ] 
	do
	    i=`expr $i + 1`
	    ( while true ; do ps xao pid,command > /dev/null 2>&1 ; done ) &
	done

The problem is where ps using /proc/%pid/mem grovels around in the
other process address room to get hold of argv.

This gets particular nasty when we have multiple copies of ps(1)
running on a SMP box:

First CPU:	running process 100 which is a "ps -ax" currently
		trying to get the argument list from process 101

Second CPU:	running process 101 which is a "ps -ax" currently
		trying to get the argument list from process 101
		(or 100 for that matter).

The code in procfs_mem.c has significant problems in this scenario,
and rather than try to hunt them down, something we should eventually
do my solution is to hang a copy of of the arg list from struct
proc and use a sysctl in the kern.proc family to access it.

My implementation has a sysctl variable which sets an upper limit
on how many bytes we use per process for this.  If this limit
is exceeded, we default to the current reality, obviously the
limit can be set to zero as well.

For anyone wanting to work on procfs_mem, setting the sysctl to
zero will revert to current behaviour so that bug is not obscured.

The arguments are stored in a separate structure which is shared
across fork and replaced in exec, so the overhead in struct proc
itself is only a pointer, and for daemons which fork a lot of
children only one copy of the arguments are stored, until they
set their own with setproctitle() that is.

The side effects of this change are many and varied:

Plus side:

1. ps(1) runs much faster and uses far fewer resources.

2. ps(1) don't need a /proc anymore.  Particular nice for chroot and jail.

3. We get access to the full command line in kernel debuggers.

4. (untested/unimplemented) /bin/ps doesn't need to be setgid 
   kmem anymore.

5. On the long run we use less memory because we don't need to i
   allocate a vnode and inode for /proc/%pid/mem.  (This is not
   implemented yet, we need to figure out how much ps(1) should
   use libkvm and fix it accordingly).

On the minus side:

1. Memory usage, if all your process have very long commandlines.
   (You can limit this with the sysctl.)

2. A process which writes to argv[0] rather than use setproctitle()
   doesn't have the desired effect.  (Setting the sysctl to zero
   solves this problem as well.)

3. If you never run ps(1) there is a epsilon sized overhead in exec(2).
   (You can make that a epsilon-squared sized overhead by setting the
   sysctl to zero.)

So expect to hear a happy Paul Saab sing our praise once again and
expect to see my commit to -current in a few moments.

--
Poul-Henning Kamp             FreeBSD coreteam member
phk@FreeBSD.ORG               "Real hackers run -current on their laptop."
FreeBSD -- It will take a long time before progress goes too far!

------- =_aaaaaaaaaa--


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?26892.942782802.1>