This reverts commit 421d95b3ea.
Ricardo correctly pointed out that there is more going on here than
typecasting. By removing the locals we are actually causing LEFT and
RIGHT to be evaluated twice which can potentially lead to some
strange side effects as:
1) VERIFY3*() causing a panic but in the panic message the values
look correct such that the assertion shouldn't fail, or:
2) if LEFT or RIGHT are expressions with side-effects (e.g. a call
to a function which changes some state), then when we panic and
examine the crash dump, it may lead to an unexpected state because
we are not expecting certain things to change during the panic,
after the expressions inside VERIFY3*(...) have been evaluated.
3) Also, it may lead to double-panics or deadlocks during panics,
like for example, if the expressions inside VERIFY3*(...) only expect
to be called once (e.g. because they acquire a mutex).
commit 421d95b3ea introduced a compiler
warning on 32-bit systems about casting a pointer to an integer of a
different size. This commit removes the warning by casting the arguments
to snprintf in the same manner as the original VERIFY3_IMPL macro.
This has a minor impact on stack usage of individual functions, but the
VERIFY macros are used so frequently that their overhead may add up.
This macro declared two new local variables to cast its argument types.
Doing the typecast inline eliminates the need for these variables.
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Some buggy NPTL threading implementations include the guard area within
the stack size allocations. In this case we need to allocate an extra
page to account for the guard area since we only have two pages of usable
stack on Linux. Added an autoconf test that detects such implementations
by running a test program designed to segfault if the bug is present.
Set a flag NPTL_GUARD_WITHIN_STACK that is tested to decide if extra
stack space must be allocated for the guard area.
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
See commit f16dec7e67fe86f3c3556a67865ee715a2964d70 for full
details of this change. But in summary -fstack-check is being
restricted in usage only to locations which must already have
small stack frames.
The stack check implementation in older versions of gcc has
a fairly low default limit on STACK_CHECK_MAX_FRAME_SIZE of
roughly 4096. This results in numerous warning when it is
used with code which was designed to run in user space and
thus may be relatively stack heavy. The avoid these warnings,
which are fatal with -Werror, this patch targets the use of
-fstack-check to libraries which are compiled in both user
space and kernel space. The only utility which uses this
flag is ztest which is designed to simulate running in the
kernel and must meet the -fstack-check requirements. All
other user space utilities do not use -fstack-check.
warning: frame size too large for reliable stack checking
warning: try reducing the number of local variables
The ZFS update to onnv_141 brought with it support for a
security label attribute called mlslabel. This feature
depends on zones to work correctly and while I originally
added minimal support for this in libspl that was a mistake.
Supporting this under Linux is not required and this is
just additional troublesome code to support. Long term
something like this could be supported under Linux but it
will need to be clearly thought through them an implemented.
For some reason which remains mysterious to me the shared library
which calls pthread_create() must be linked with -pthread. If this
is not done on 32-bit system the default ulimit stack size is used.
Surprisingly, on a 64-bit system the stack limit specified by the
pthread_attr is honored even when -pthread is not passed when linking
the shared library.
The following files were being left out the tarball which
is used by the 'make rpm' target. This results in a build
failure when building packages which use the tarball.
lib/libspl/include/sys/tsol/*.h
lib/libspl/include/util/*.h
It turns out the gcc option -Wframe-larger-than=<size> which I recently
added to the build system is not supported in older versions of gcc.
Since this is just a flag to ensure I keep stack usage under control
I've added a configure check to detect if gcc supports it. If it's
available we use it in the proper places, if it's not we don't.
For all module/library functions ensure so stack frame exceeds 1024
bytes. Ideally this should be set lower to say 512 bytes but there
are still numerous functions which exceed even this limit. For now
this is set to 1024 to ensure we catch the worst offenders.
Additionally, set the limit for ztest to 1024 bytes since the idea
here is to catch stack issues in user space before we find them by
overrunning a kernel stack. This should also be reduced to 512
bytes as soon as all the trouble makes are fixed.
Finally, add -fstack-check to gcc build options when --enable-debug
is specified at configure time. This ensures that each page on the
stack will be touched and we will generate a segfault on stack
overflow.
Over time we can gradually fix the following functions:
536 zfs:dsl_deadlist_regenerate
536 zfs:dsl_load_sets
536 zfs:zil_parse
544 zfs:zfs_ioc_recv
552 zfs:dsl_deadlist_insert_bpobj
552 zfs:vdev_dtl_sync
584 zfs:copy_create_perms
608 zfs:ddt_class_contains
608 zfs:ddt_prefetch
608 zfs:__dprintf
616 zfs:ddt_lookup
648 zfs:dsl_scan_ddt
696 zfs:dsl_deadlist_merge
736 zfs:ddt_zap_walk
744 zfs:dsl_prop_get_all_impl
872 zfs:dnode_evict_dbufs
There are 3 fixes in thie commit. First, update ztest_run() to store
the thread id and not the address of the kthread_t. This will be freed
on thread exit and is not safe to use. This is pretty close to how
things were done in the original ztest code before I got there.
Second, for extra paranoia update thread_exit() to return a special
TS_MAGIC value via pthread_exit(). This value is then verified in
pthread_join() to ensure the thread exited cleanly. This can be
done cleanly because the kthread doesn't provide a return code
mechanism we need to worry about.
Third, replace the ztest deadman thread with a signal handler. We
cannot use the previous approach because the correct behavior for
pthreads is to wait for all threads to exit before terminating the
process. Since the deadman thread won't call exit by design we
end up hanging in kernel_exit(). To avoid this we just setup a
SIGALRM signal handle and register a deadman alarm. IMHO this
is simpler and cleaner anyway.
There was previous discussion of a race with joinable threads but to
be honest I can neither exactly remember the race, or recrease the
issue. I believe it may have had to do with pthread_create() returning
without having set kt->tid since this was done in the created thread.
If that was the race then I've 'fixed' it by ensuring the thread id
is set in the thread AND as the first pthread_create() argument. Why
this wasn't done originally I'm not sure, with luck Ricardo remembers.
Additionally, explicitly set a PAGESIZE guard frame at the end of the
stack to aid in detecting stack overflow. And add some conditional
logic to set STACK_SIZE correctly for Solaris.
Certain function must never be automatically inlined by gcc because
they are stack heavy or called recursively. This patch flags all
such functions I have found as 'noinline' to prevent gcc from making
the optimization.