summaryrefslogtreecommitdiffstats
path: root/util/oslib-posix.c
diff options
context:
space:
mode:
authorPeter Maydell2016-10-04 15:25:08 +0200
committerPeter Maydell2016-10-04 15:25:08 +0200
commitbbc4c3f4f3c624e2de64fdcb79f4dd8c1a508e9d (patch)
treeacd2201a7f374badd8c9f16c9917a6e93af40285 /util/oslib-posix.c
parentMerge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20161004'... (diff)
parentoslib-posix: add a configure switch to debug stack usage (diff)
downloadqemu-bbc4c3f4f3c624e2de64fdcb79f4dd8c1a508e9d.tar.gz
qemu-bbc4c3f4f3c624e2de64fdcb79f4dd8c1a508e9d.tar.xz
qemu-bbc4c3f4f3c624e2de64fdcb79f4dd8c1a508e9d.zip
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
Block layer patches # gpg: Signature made Thu 29 Sep 2016 14:11:30 BST # gpg: using RSA key 0x7F09B272C88F2FD6 # gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>" # Primary key fingerprint: DC3D EB15 9A9A F95D 3D74 56FE 7F09 B272 C88F 2FD6 * remotes/kevin/tags/for-upstream: oslib-posix: add a configure switch to debug stack usage coroutine-sigaltstack: use helper for allocating stack memory coroutine-ucontext: use helper for allocating stack memory coroutine: add a macro for the coroutine stack size coroutine-sigaltstack: rename coroutine struct appropriately oslib-posix: add helpers for stack alloc and free block: Remove qemu_root_bds_opts block: Move 'discard' option to bdrv_open_common() block: Use 'detect-zeroes' option for 'blockdev-change-medium' block: Parse 'detect-zeroes' in bdrv_open_common() block/qapi: Move 'aio' option to file driver block/qapi: Use separate options type for curl driver block: Drop aio/cache consistency check from qmp_blockdev_add() block: Fix error path in qmp_blockdev_change_medium() block-backend: remove blk_flush_all qemu: use bdrv_flush_all for vm_stop et al block: reintroduce bdrv_flush_all Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'util/oslib-posix.c')
-rw-r--r--util/oslib-posix.c77
1 files changed, 77 insertions, 0 deletions
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
index f2d4e9e592..aaec1891f5 100644
--- a/util/oslib-posix.c
+++ b/util/oslib-posix.c
@@ -50,6 +50,10 @@
#include "qemu/mmap-alloc.h"
+#ifdef CONFIG_DEBUG_STACK_USAGE
+#include "qemu/error-report.h"
+#endif
+
int qemu_get_thread_id(void)
{
#if defined(__linux__)
@@ -499,3 +503,76 @@ pid_t qemu_fork(Error **errp)
}
return pid;
}
+
+void *qemu_alloc_stack(size_t *sz)
+{
+ void *ptr, *guardpage;
+#ifdef CONFIG_DEBUG_STACK_USAGE
+ void *ptr2;
+#endif
+ size_t pagesz = getpagesize();
+#ifdef _SC_THREAD_STACK_MIN
+ /* avoid stacks smaller than _SC_THREAD_STACK_MIN */
+ long min_stack_sz = sysconf(_SC_THREAD_STACK_MIN);
+ *sz = MAX(MAX(min_stack_sz, 0), *sz);
+#endif
+ /* adjust stack size to a multiple of the page size */
+ *sz = ROUND_UP(*sz, pagesz);
+ /* allocate one extra page for the guard page */
+ *sz += pagesz;
+
+ ptr = mmap(NULL, *sz, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ if (ptr == MAP_FAILED) {
+ abort();
+ }
+
+#if defined(HOST_IA64)
+ /* separate register stack */
+ guardpage = ptr + (((*sz - pagesz) / 2) & ~pagesz);
+#elif defined(HOST_HPPA)
+ /* stack grows up */
+ guardpage = ptr + *sz - pagesz;
+#else
+ /* stack grows down */
+ guardpage = ptr;
+#endif
+ if (mprotect(guardpage, pagesz, PROT_NONE) != 0) {
+ abort();
+ }
+
+#ifdef CONFIG_DEBUG_STACK_USAGE
+ for (ptr2 = ptr + pagesz; ptr2 < ptr + *sz; ptr2 += sizeof(uint32_t)) {
+ *(uint32_t *)ptr2 = 0xdeadbeaf;
+ }
+#endif
+
+ return ptr;
+}
+
+#ifdef CONFIG_DEBUG_STACK_USAGE
+static __thread unsigned int max_stack_usage;
+#endif
+
+void qemu_free_stack(void *stack, size_t sz)
+{
+#ifdef CONFIG_DEBUG_STACK_USAGE
+ unsigned int usage;
+ void *ptr;
+
+ for (ptr = stack + getpagesize(); ptr < stack + sz;
+ ptr += sizeof(uint32_t)) {
+ if (*(uint32_t *)ptr != 0xdeadbeaf) {
+ break;
+ }
+ }
+ usage = sz - (uintptr_t) (ptr - stack);
+ if (usage > max_stack_usage) {
+ error_report("thread %d max stack usage increased from %u to %u",
+ qemu_get_thread_id(), max_stack_usage, usage);
+ max_stack_usage = usage;
+ }
+#endif
+
+ munmap(stack, sz);
+}