mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-12-11 16:00:50 -07:00
Block layer patches
-----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQIcBAABAgAGBQJX7RMCAAoJEH8JsnLIjy/Wa3YQAIZkhb0XpWSbGjS0N3VsqI+P IqkwXDkYf7H02sptgGJtb0uHxsIdeTUv7B5NKld7FhAC2UNqrP6IZLiZUM3/yvCB oWITyfM3Y35OJi+hR4I4s+8lPaOjXyonBrBBOhipMqBkkgQ7Ck+ZhSWr4lDvo9oe BLijZLEVRZQdimAz82VDtBFW4jwjPzj8RBLfFDI8HThrQ2DMmt0DTHWywTVi/Lkj 4qa0lUzVXRRaroyRFzu2T2joakzgaj9TH7/o5RZS2hcEsiaj4Sd7o6+UmKlSk/7v JjjgFpNXDW0Lm7Hm14ldp6zQSJ4yCraFBv/edzJ7KvpD04ESWNQQm6ABHaAlfdpL I6M8x/8v20tPMaAA0l3KTAuWzyq9Ihu7SK4pifhPazbpl/bEUzovHm4vjV/RIdHO AIojs7w9vBGxOaxlQyPchTj8bqOkZbdNTClj6HEEOc6V4SIIzg4PgC4gFu8yX88u NxOaLQvXUSVONWGKQ3SC7PSY+vxTGRerQZ8a7TGitSZFvPD0w7QR+DYeqUPBoQtO m6P9+QfZ6Lzqm2UD2e2oY0GYQE08jjE5J6V4rF6lNaYO2TL2elw8Cg1lKImtggST K1rFfg4Fhraqk2g7MrJoa9LBkul/0G1OfcCgbWwfWyv/FA9kNyvwHCLcPLqrCd8S 1OBjN2A6WlIS6gfCRQUt =6HYD -----END PGP SIGNATURE----- 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>
This commit is contained in:
commit
bbc4c3f4f3
21 changed files with 342 additions and 191 deletions
|
|
@ -33,8 +33,9 @@
|
|||
typedef struct {
|
||||
Coroutine base;
|
||||
void *stack;
|
||||
size_t stack_size;
|
||||
sigjmp_buf env;
|
||||
} CoroutineUContext;
|
||||
} CoroutineSigAltStack;
|
||||
|
||||
/**
|
||||
* Per-thread coroutine bookkeeping
|
||||
|
|
@ -44,7 +45,7 @@ typedef struct {
|
|||
Coroutine *current;
|
||||
|
||||
/** The default coroutine */
|
||||
CoroutineUContext leader;
|
||||
CoroutineSigAltStack leader;
|
||||
|
||||
/** Information for the signal handler (trampoline) */
|
||||
sigjmp_buf tr_reenter;
|
||||
|
|
@ -89,7 +90,7 @@ static void __attribute__((constructor)) coroutine_init(void)
|
|||
* (from the signal handler when it is not signal handling, read ahead
|
||||
* for more information).
|
||||
*/
|
||||
static void coroutine_bootstrap(CoroutineUContext *self, Coroutine *co)
|
||||
static void coroutine_bootstrap(CoroutineSigAltStack *self, Coroutine *co)
|
||||
{
|
||||
/* Initialize longjmp environment and switch back the caller */
|
||||
if (!sigsetjmp(self->env, 0)) {
|
||||
|
|
@ -109,7 +110,7 @@ static void coroutine_bootstrap(CoroutineUContext *self, Coroutine *co)
|
|||
*/
|
||||
static void coroutine_trampoline(int signal)
|
||||
{
|
||||
CoroutineUContext *self;
|
||||
CoroutineSigAltStack *self;
|
||||
Coroutine *co;
|
||||
CoroutineThreadState *coTS;
|
||||
|
||||
|
|
@ -143,8 +144,7 @@ static void coroutine_trampoline(int signal)
|
|||
|
||||
Coroutine *qemu_coroutine_new(void)
|
||||
{
|
||||
const size_t stack_size = 1 << 20;
|
||||
CoroutineUContext *co;
|
||||
CoroutineSigAltStack *co;
|
||||
CoroutineThreadState *coTS;
|
||||
struct sigaction sa;
|
||||
struct sigaction osa;
|
||||
|
|
@ -164,7 +164,8 @@ Coroutine *qemu_coroutine_new(void)
|
|||
*/
|
||||
|
||||
co = g_malloc0(sizeof(*co));
|
||||
co->stack = g_malloc(stack_size);
|
||||
co->stack_size = COROUTINE_STACK_SIZE;
|
||||
co->stack = qemu_alloc_stack(&co->stack_size);
|
||||
co->base.entry_arg = &old_env; /* stash away our jmp_buf */
|
||||
|
||||
coTS = coroutine_get_thread_state();
|
||||
|
|
@ -189,7 +190,7 @@ Coroutine *qemu_coroutine_new(void)
|
|||
* Set the new stack.
|
||||
*/
|
||||
ss.ss_sp = co->stack;
|
||||
ss.ss_size = stack_size;
|
||||
ss.ss_size = co->stack_size;
|
||||
ss.ss_flags = 0;
|
||||
if (sigaltstack(&ss, &oss) < 0) {
|
||||
abort();
|
||||
|
|
@ -251,17 +252,17 @@ Coroutine *qemu_coroutine_new(void)
|
|||
|
||||
void qemu_coroutine_delete(Coroutine *co_)
|
||||
{
|
||||
CoroutineUContext *co = DO_UPCAST(CoroutineUContext, base, co_);
|
||||
CoroutineSigAltStack *co = DO_UPCAST(CoroutineSigAltStack, base, co_);
|
||||
|
||||
g_free(co->stack);
|
||||
qemu_free_stack(co->stack, co->stack_size);
|
||||
g_free(co);
|
||||
}
|
||||
|
||||
CoroutineAction qemu_coroutine_switch(Coroutine *from_, Coroutine *to_,
|
||||
CoroutineAction action)
|
||||
{
|
||||
CoroutineUContext *from = DO_UPCAST(CoroutineUContext, base, from_);
|
||||
CoroutineUContext *to = DO_UPCAST(CoroutineUContext, base, to_);
|
||||
CoroutineSigAltStack *from = DO_UPCAST(CoroutineSigAltStack, base, from_);
|
||||
CoroutineSigAltStack *to = DO_UPCAST(CoroutineSigAltStack, base, to_);
|
||||
CoroutineThreadState *s = coroutine_get_thread_state();
|
||||
int ret;
|
||||
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
typedef struct {
|
||||
Coroutine base;
|
||||
void *stack;
|
||||
size_t stack_size;
|
||||
sigjmp_buf env;
|
||||
|
||||
#ifdef CONFIG_VALGRIND_H
|
||||
|
|
@ -82,7 +83,6 @@ static void coroutine_trampoline(int i0, int i1)
|
|||
|
||||
Coroutine *qemu_coroutine_new(void)
|
||||
{
|
||||
const size_t stack_size = 1 << 20;
|
||||
CoroutineUContext *co;
|
||||
ucontext_t old_uc, uc;
|
||||
sigjmp_buf old_env;
|
||||
|
|
@ -101,17 +101,18 @@ Coroutine *qemu_coroutine_new(void)
|
|||
}
|
||||
|
||||
co = g_malloc0(sizeof(*co));
|
||||
co->stack = g_malloc(stack_size);
|
||||
co->stack_size = COROUTINE_STACK_SIZE;
|
||||
co->stack = qemu_alloc_stack(&co->stack_size);
|
||||
co->base.entry_arg = &old_env; /* stash away our jmp_buf */
|
||||
|
||||
uc.uc_link = &old_uc;
|
||||
uc.uc_stack.ss_sp = co->stack;
|
||||
uc.uc_stack.ss_size = stack_size;
|
||||
uc.uc_stack.ss_size = co->stack_size;
|
||||
uc.uc_stack.ss_flags = 0;
|
||||
|
||||
#ifdef CONFIG_VALGRIND_H
|
||||
co->valgrind_stack_id =
|
||||
VALGRIND_STACK_REGISTER(co->stack, co->stack + stack_size);
|
||||
VALGRIND_STACK_REGISTER(co->stack, co->stack + co->stack_size);
|
||||
#endif
|
||||
|
||||
arg.p = co;
|
||||
|
|
@ -149,7 +150,7 @@ void qemu_coroutine_delete(Coroutine *co_)
|
|||
valgrind_stack_deregister(co);
|
||||
#endif
|
||||
|
||||
g_free(co->stack);
|
||||
qemu_free_stack(co->stack, co->stack_size);
|
||||
g_free(co);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ static void CALLBACK coroutine_trampoline(void *co_)
|
|||
|
||||
Coroutine *qemu_coroutine_new(void)
|
||||
{
|
||||
const size_t stack_size = 1 << 20;
|
||||
const size_t stack_size = COROUTINE_STACK_SIZE;
|
||||
CoroutineWin32 *co;
|
||||
|
||||
co = g_malloc0(sizeof(*co));
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue