Date: Wed, 26 Oct 2011 23:25:43 +0300 From: Kostik Belousov <kostikbel@gmail.com> To: Alexandr Matveev <timon@timon.net.nz> Cc: hackers@freebsd.org Subject: Re: sigprocmask and fork Message-ID: <20111026202542.GG50300@deviant.kiev.zoral.com.ua> In-Reply-To: <4EA804C8.2030900@timon.net.nz> References: <4EA804C8.2030900@timon.net.nz>
next in thread | previous in thread | raw e-mail | index | archive | help
--8yqj9JR9W5krfwRp Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Wed, Oct 26, 2011 at 05:02:00PM +0400, Alexandr Matveev wrote: > Hi, >=20 > We are using FreeBSD 8.2 on our servers for high load projects. > When I was preparing system for production I saw strange (as I think)=20 > behavior, > that leads to increased load on servers. >=20 > If I made truss on httpd (apache22) process, I saw too much sigprocmask= =20 > syscalls: >=20 > 24822: sigprocmask(SIG_BLOCK,0x0,0x0) =3D 0 (0x0) > 24822: sigprocmask(SIG_BLOCK,0x0,0x0) =3D 0 (0x0) > 24822: sigprocmask(SIG_BLOCK,0x0,0x0) =3D 0 (0x0) > 24822: sigprocmask(SIG_BLOCK,0x0,0x0) =3D 0 (0x0) > 24822: sigprocmask(SIG_BLOCK,0x0,0x0) =3D 0 (0x0) > ... too many lines ... >=20 > and >=20 > 24822: > sigprocmask(SIG_BLOCK,SIGHUP|SIGINT|SIGQUIT|SIGKILL|SIGPIPE|SIGALRM|SIGTE= RM|SIGURG|SIGSTOP|SIGTSTP|SIGCONT|SIGCHLD|SIGTTIN|SIGTTOU|SIGIO|SIGXCPU|SIG= XFSZ|SIGVTALRM|SIGPROF|S=20 >=20 > IGWINCH|SIGINFO|SIGUSR1|SIGUSR2,0x0) =3D 0 (0x0) > 24822: sigprocmask(SIG_SETMASK,0x0,0x0) =3D 0 (0x0) > 24822: > sigprocmask(SIG_BLOCK,SIGHUP|SIGINT|SIGQUIT|SIGKILL|SIGPIPE|SIGALRM|SIGTE= RM|SIGURG|SIGSTOP|SIGTSTP|SIGCONT|SIGCHLD|SIGTTIN|SIGTTOU|SIGIO|SIGXCPU|SIG= XFSZ|SIGVTALRM|SIGPROF|S=20 >=20 > IGWINCH|SIGINFO|SIGUSR1|SIGUSR2,0x0) =3D 0 (0x0) > 24822: sigprocmask(SIG_SETMASK,0x0,0x0) =3D 0 (0x0) > 24822: > sigprocmask(SIG_BLOCK,SIGHUP|SIGINT|SIGQUIT|SIGKILL|SIGPIPE|SIGALRM|SIGTE= RM|SIGURG|SIGSTOP|SIGTSTP|SIGCONT|SIGCHLD|SIGTTIN|SIGTTOU|SIGIO|SIGXCPU|SIG= XFSZ|SIGVTALRM|SIGPROF|S=20 >=20 > IGWINCH|SIGINFO|SIGUSR1|SIGUSR2,0x0) =3D 0 (0x0) > 24822: sigprocmask(SIG_SETMASK,0x0,0x0) =3D 0 (0x0) > ... too many lines ... >=20 >=20 > but apache, and modules loaded from it do not call this directly. > I was trying to use DTRACE for getting information about syscalls, and I > got same result. >=20 > I wrote a tiny sample >=20 > code: > $ cat sigproc_test.c > #include<unistd.h> >=20 > main() > { > fork(); > } > I ran it on FreeBSD with different compilers: > $ cc sigproc_test.c -o sigproc_test > $ truss ./sigproc_test 2>&1 | grep sigprocmask | wc -l > 8 > $ g++ sigproc_test.c -o sigproc_test > $ truss ./sigproc_test 2>&1 | grep sigprocmask | wc -l > 20 >=20 > Is it normal to make so many sigprocmask syscalls for such simple program? > For example, there is no sigprocmask syscalls when I run it on Debian=20 > Linux. Yes, it is normal. I do not quite understand the relation between "simple program" and "so many sigprocmask syscalls" claim, but alas. The calls to sigprocmask originate from the rtld, which needs to guarantee async-signal safety of the lazy binding process. The rtld locks, besides other things, block signals. Also, due to an additional requirement that rtld is functional after the fork, it has to acquire the internal locks around fork in multithreaded programs. All lock acquisions in the program which does only one fork(2) call in main(), as well as in the program that does nothing in main at all, come from the rtld initialization before main, and shared library finalizations after. For empty main(), there are 4 locks acquisions after return from main, so you get total 12 for forked version. In essence, the trivial program makes the same amount of locking in the startup/exit path, as non-trivial (the cost is proportional to the number of shared libraries loaded). The typical cause for the rtld locks acquisitions during the program execution, besides the dlopen(3) activity, is the lazy resolution of the PLT entries. LD_BIND_NOW=3D1 moves the load to the program startup. >=20 > Another sample. Here we have sigprocmask syscalls on Linux too, but=20 > FreeBSD makes this syscall significantly more often: > $ cat test.c > #include<unistd.h> >=20 > main() > { > int i; > sleep(2); > for (i =3D 0; i<3; i++) { > int pid =3D fork(); > if (!pid) { > sleep(0.5); > return 0; > } > sleep(2); > } > } >=20 > FreeBSD 8.2: > # truss -f ./test > ... SKIPPED ... > 48666:=20 > sigprocmask(SIG_BLOCK,SIGHUP|SIGINT|SIGQUIT|SIGKILL|SIGPIPE|SIGALRM|SIGTE= RM|SIGURG|SIGSTOP|SIGTSTP|SIGCONT|SIGCHLD|SIGTTIN|SIGTTOU|SIGIO|SIGXCPU|SIG= XFSZ|SIGVTALRM|SIGPROF|SIGWINCH|SIGINFO|SIGUSR1|SIGUSR2,0x0)=20 > =3D 0 (0x0) > 48666: sigprocmask(SIG_SETMASK,0x0,0x0) =3D 0 (0x0) > 48666: __sysctl(0xbfbfe6a4,0x2,0x28192700,0xbfbfe6ac,0x0,0x0) =3D 0 (0x0) > 48666:=20 > sigprocmask(SIG_BLOCK,SIGHUP|SIGINT|SIGQUIT|SIGKILL|SIGPIPE|SIGALRM|SIGTE= RM|SIGURG|SIGSTOP|SIGTSTP|SIGCONT|SIGCHLD|SIGTTIN|SIGTTOU|SIGIO|SIGXCPU|SIG= XFSZ|SIGVTALRM|SIGPROF|SIGWINCH|SIGINFO|SIGUSR1|SIGUSR2,0x0)=20 > =3D 0 (0x0) > 48666: sigprocmask(SIG_SETMASK,0x0,0x0) =3D 0 (0x0) > 48666: nanosleep({2.000000000 }) =3D 0 (0x0) > 48666: fork() =3D 48667 (0xbe1b) > 48667: sigprocmask(SIG_SETMASK,0x0,0x0) =3D 0 (0x0) > 48667:=20 > sigprocmask(SIG_BLOCK,SIGHUP|SIGINT|SIGQUIT|SIGKILL|SIGPIPE|SIGALRM|SIGTE= RM|SIGURG|SIGSTOP|SIGTSTP|SIGCONT|SIGCHLD|SIGTTIN|SIGTTOU|SIGIO|SIGXCPU|SIG= XFSZ|SIGVTALRM|SIGPROF|SIGWINCH|SIGINFO|SIGUSR1|SIGUSR2,0x0)=20 > =3D 0 (0x0) > 48667: sigprocmask(SIG_SETMASK,0x0,0x0) =3D 0 (0x0) > 48667: process exit, rval =3D 0 > 48666: nanosleep({2.000000000 }) =3D 0 (0x0) > 48666: fork() =3D 48669 (0xbe1d) > 48669:=20 > sigprocmask(SIG_BLOCK,SIGHUP|SIGINT|SIGQUIT|SIGKILL|SIGPIPE|SIGALRM|SIGTE= RM|SIGURG|SIGSTOP|SIGTSTP|SIGCONT|SIGCHLD|SIGTTIN|SIGTTOU|SIGIO|SIGXCPU|SIG= XFSZ|SIGVTALRM|SIGPROF|SIGWINCH|SIGINFO|SIGUSR1|SIGUSR2,0x0)=20 > =3D 0 (0x0) > 48669: sigprocmask(SIG_SETMASK,0x0,0x0) =3D 0 (0x0) > 48669: process exit, rval =3D 0 > 48666: nanosleep({2.000000000 }) =3D 0 (0x0) > 48666: fork() =3D 48674 (0xbe22) > 48674: sigprocmask(SIG_SETMASK,0x0,0x0) =3D 0 (0x0) > 48674:=20 > sigprocmask(SIG_BLOCK,SIGHUP|SIGINT|SIGQUIT|SIGKILL|SIGPIPE|SIGALRM|SIGTE= RM|SIGURG|SIGSTOP|SIGTSTP|SIGCONT|SIGCHLD|SIGTTIN|SIGTTOU|SIGIO|SIGXCPU|SIG= XFSZ|SIGVTALRM|SIGPROF|SIGWINCH|SIGINFO|SIGUSR1|SIGUSR2,0x0)=20 > =3D 0 (0x0) > 48674: sigprocmask(SIG_SETMASK,0x0,0x0) =3D 0 (0x0) > 48674: process exit, rval =3D 0 > 48666: nanosleep({2.000000000 }) =3D 0 (0x0) > 48666:=20 > sigprocmask(SIG_BLOCK,SIGHUP|SIGINT|SIGQUIT|SIGKILL|SIGPIPE|SIGALRM|SIGTE= RM|SIGURG|SIGSTOP|SIGTSTP|SIGCONT|SIGCHLD|SIGTTIN|SIGTTOU|SIGIO|SIGXCPU|SIG= XFSZ|SIGVTALRM|SIGPROF|SIGWINCH|SIGINFO|SIGUSR1|SIGUSR2,0x0)=20 > =3D 0 (0x0) > 48666: sigprocmask(SIG_SETMASK,0x0,0x0) =3D 0 (0x0) > 48666:=20 > sigprocmask(SIG_BLOCK,SIGHUP|SIGINT|SIGQUIT|SIGKILL|SIGPIPE|SIGALRM|SIGTE= RM|SIGURG|SIGSTOP|SIGTSTP|SIGCONT|SIGCHLD|SIGTTIN|SIGTTOU|SIGIO|SIGXCPU|SIG= XFSZ|SIGVTALRM|SIGPROF|SIGWINCH|SIGINFO|SIGUSR1|SIGUSR2,0x0)=20 > =3D 0 (0x0) > 48666: sigprocmask(SIG_SETMASK,0x0,0x0) =3D 0 (0x0) > 48666: process exit, rval =3D 0 >=20 > Linux: > # strace ./test > ... SKIPPED ... > rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) =3D 0 > rt_sigaction(SIGCHLD, NULL, {SIG_DFL, [], 0}, 8) =3D 0 > rt_sigprocmask(SIG_SETMASK, [], NULL, 8) =3D 0 > nanosleep({2, 0}, 0x7fff0e6b7050) =3D 0 > clone(child_stack=3D0,=20 > flags=3DCLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD,=20 > child_tidptr=3D0x7fb553b0d9d0) =3D 24310 > rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) =3D 0 > rt_sigaction(SIGCHLD, NULL, {SIG_DFL, [], 0}, 8) =3D 0 > rt_sigprocmask(SIG_SETMASK, [], NULL, 8) =3D 0 > --- SIGCHLD (Child exited) @ 0 (0) --- > nanosleep({2, 0}, 0x7fff0e6b7050) =3D 0 > clone(child_stack=3D0,=20 > flags=3DCLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD,=20 > child_tidptr=3D0x7fb553b0d9d0) =3D 24311 > rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) =3D 0 > rt_sigaction(SIGCHLD, NULL, {SIG_DFL, [], 0}, 8) =3D 0 > rt_sigprocmask(SIG_SETMASK, [], NULL, 8) =3D 0 > --- SIGCHLD (Child exited) @ 0 (0) --- > nanosleep({2, 0}, 0x7fff0e6b7050) =3D 0 > clone(child_stack=3D0,=20 > flags=3DCLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD,=20 > child_tidptr=3D0x7fb553b0d9d0) =3D 24312 > rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) =3D 0 > rt_sigaction(SIGCHLD, NULL, {SIG_DFL, [], 0}, 8) =3D 0 > rt_sigprocmask(SIG_SETMASK, [], NULL, 8) =3D 0 > --- SIGCHLD (Child exited) @ 0 (0) --- > nanosleep({2, 0}, 0x7fff0e6b7050) =3D 0 > exit_group(0) =3D ? >=20 > --=20 > Alexander Matveev > .masterhost >=20 >=20 > _______________________________________________ > freebsd-hackers@freebsd.org mailing list > http://lists.freebsd.org/mailman/listinfo/freebsd-hackers > To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@freebsd.org" --8yqj9JR9W5krfwRp Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.18 (FreeBSD) iEYEARECAAYFAk6obMYACgkQC3+MBN1Mb4jt2QCg5Dvbl2nqUA/byNcicOzwwbuZ +3kAoKfcHTYn7saxEK4111GSxUx1zV36 =qfbX -----END PGP SIGNATURE----- --8yqj9JR9W5krfwRp--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20111026202542.GG50300>