Skip to content

Commit

Permalink
io: mark mixed functions that can suspend
Browse files Browse the repository at this point in the history
There should be no paths from a coroutine_fn to aio_poll, however in
practice coroutine_mixed_fn will call aio_poll in the !qemu_in_coroutine()
path.  By marking mixed functions, we can track accurately the call paths
that execute entirely in coroutine context, and find more missing
coroutine_fn markers.  This results in more accurate checks that
coroutine code does not end up blocking.

If the marking were extended transitively to all functions that call
these ones, static analysis could be done much more efficiently.
However, this is a start and makes it possible to use vrc's path-based
searches to find potential bugs where coroutine_fns call blocking functions.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
  • Loading branch information
bonzini committed Apr 20, 2023
1 parent cf9d4e6 commit 1dd91b2
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 78 deletions.
78 changes: 39 additions & 39 deletions include/io/channel.h
Original file line number Diff line number Diff line change
Expand Up @@ -301,10 +301,10 @@ ssize_t qio_channel_writev_full(QIOChannel *ioc,
* Returns: 1 if all bytes were read, 0 if end-of-file
* occurs without data, or -1 on error
*/
int qio_channel_readv_all_eof(QIOChannel *ioc,
const struct iovec *iov,
size_t niov,
Error **errp);
int coroutine_mixed_fn qio_channel_readv_all_eof(QIOChannel *ioc,
const struct iovec *iov,
size_t niov,
Error **errp);

/**
* qio_channel_readv_all:
Expand All @@ -328,10 +328,10 @@ int qio_channel_readv_all_eof(QIOChannel *ioc,
*
* Returns: 0 if all bytes were read, or -1 on error
*/
int qio_channel_readv_all(QIOChannel *ioc,
const struct iovec *iov,
size_t niov,
Error **errp);
int coroutine_mixed_fn qio_channel_readv_all(QIOChannel *ioc,
const struct iovec *iov,
size_t niov,
Error **errp);


/**
Expand All @@ -353,10 +353,10 @@ int qio_channel_readv_all(QIOChannel *ioc,
*
* Returns: 0 if all bytes were written, or -1 on error
*/
int qio_channel_writev_all(QIOChannel *ioc,
const struct iovec *iov,
size_t niov,
Error **errp);
int coroutine_mixed_fn qio_channel_writev_all(QIOChannel *ioc,
const struct iovec *iov,
size_t niov,
Error **errp);

/**
* qio_channel_readv:
Expand Down Expand Up @@ -437,10 +437,10 @@ ssize_t qio_channel_write(QIOChannel *ioc,
* Returns: 1 if all bytes were read, 0 if end-of-file occurs
* without data, or -1 on error
*/
int qio_channel_read_all_eof(QIOChannel *ioc,
char *buf,
size_t buflen,
Error **errp);
int coroutine_mixed_fn qio_channel_read_all_eof(QIOChannel *ioc,
char *buf,
size_t buflen,
Error **errp);

/**
* qio_channel_read_all:
Expand All @@ -457,10 +457,10 @@ int qio_channel_read_all_eof(QIOChannel *ioc,
*
* Returns: 0 if all bytes were read, or -1 on error
*/
int qio_channel_read_all(QIOChannel *ioc,
char *buf,
size_t buflen,
Error **errp);
int coroutine_mixed_fn qio_channel_read_all(QIOChannel *ioc,
char *buf,
size_t buflen,
Error **errp);

/**
* qio_channel_write_all:
Expand All @@ -476,10 +476,10 @@ int qio_channel_read_all(QIOChannel *ioc,
*
* Returns: 0 if all bytes were written, or -1 on error
*/
int qio_channel_write_all(QIOChannel *ioc,
const char *buf,
size_t buflen,
Error **errp);
int coroutine_mixed_fn qio_channel_write_all(QIOChannel *ioc,
const char *buf,
size_t buflen,
Error **errp);

/**
* qio_channel_set_blocking:
Expand Down Expand Up @@ -812,11 +812,11 @@ void qio_channel_set_aio_fd_handler(QIOChannel *ioc,
* occurs without data, or -1 on error
*/

int qio_channel_readv_full_all_eof(QIOChannel *ioc,
const struct iovec *iov,
size_t niov,
int **fds, size_t *nfds,
Error **errp);
int coroutine_mixed_fn qio_channel_readv_full_all_eof(QIOChannel *ioc,
const struct iovec *iov,
size_t niov,
int **fds, size_t *nfds,
Error **errp);

/**
* qio_channel_readv_full_all:
Expand All @@ -838,11 +838,11 @@ int qio_channel_readv_full_all_eof(QIOChannel *ioc,
* Returns: 0 if all bytes were read, or -1 on error
*/

int qio_channel_readv_full_all(QIOChannel *ioc,
const struct iovec *iov,
size_t niov,
int **fds, size_t *nfds,
Error **errp);
int coroutine_mixed_fn qio_channel_readv_full_all(QIOChannel *ioc,
const struct iovec *iov,
size_t niov,
int **fds, size_t *nfds,
Error **errp);

/**
* qio_channel_writev_full_all:
Expand Down Expand Up @@ -872,11 +872,11 @@ int qio_channel_readv_full_all(QIOChannel *ioc,
* Returns: 0 if all bytes were written, or -1 on error
*/

int qio_channel_writev_full_all(QIOChannel *ioc,
const struct iovec *iov,
size_t niov,
int *fds, size_t nfds,
int flags, Error **errp);
int coroutine_mixed_fn qio_channel_writev_full_all(QIOChannel *ioc,
const struct iovec *iov,
size_t niov,
int *fds, size_t nfds,
int flags, Error **errp);

/**
* qio_channel_flush:
Expand Down
78 changes: 39 additions & 39 deletions io/channel.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,27 +109,27 @@ ssize_t qio_channel_writev_full(QIOChannel *ioc,
}


int qio_channel_readv_all_eof(QIOChannel *ioc,
const struct iovec *iov,
size_t niov,
Error **errp)
int coroutine_mixed_fn qio_channel_readv_all_eof(QIOChannel *ioc,
const struct iovec *iov,
size_t niov,
Error **errp)
{
return qio_channel_readv_full_all_eof(ioc, iov, niov, NULL, NULL, errp);
}

int qio_channel_readv_all(QIOChannel *ioc,
const struct iovec *iov,
size_t niov,
Error **errp)
int coroutine_mixed_fn qio_channel_readv_all(QIOChannel *ioc,
const struct iovec *iov,
size_t niov,
Error **errp)
{
return qio_channel_readv_full_all(ioc, iov, niov, NULL, NULL, errp);
}

int qio_channel_readv_full_all_eof(QIOChannel *ioc,
const struct iovec *iov,
size_t niov,
int **fds, size_t *nfds,
Error **errp)
int coroutine_mixed_fn qio_channel_readv_full_all_eof(QIOChannel *ioc,
const struct iovec *iov,
size_t niov,
int **fds, size_t *nfds,
Error **errp)
{
int ret = -1;
struct iovec *local_iov = g_new(struct iovec, niov);
Expand Down Expand Up @@ -215,11 +215,11 @@ int qio_channel_readv_full_all_eof(QIOChannel *ioc,
return ret;
}

int qio_channel_readv_full_all(QIOChannel *ioc,
const struct iovec *iov,
size_t niov,
int **fds, size_t *nfds,
Error **errp)
int coroutine_mixed_fn qio_channel_readv_full_all(QIOChannel *ioc,
const struct iovec *iov,
size_t niov,
int **fds, size_t *nfds,
Error **errp)
{
int ret = qio_channel_readv_full_all_eof(ioc, iov, niov, fds, nfds, errp);

Expand All @@ -234,19 +234,19 @@ int qio_channel_readv_full_all(QIOChannel *ioc,
return ret;
}

int qio_channel_writev_all(QIOChannel *ioc,
const struct iovec *iov,
size_t niov,
Error **errp)
int coroutine_mixed_fn qio_channel_writev_all(QIOChannel *ioc,
const struct iovec *iov,
size_t niov,
Error **errp)
{
return qio_channel_writev_full_all(ioc, iov, niov, NULL, 0, 0, errp);
}

int qio_channel_writev_full_all(QIOChannel *ioc,
const struct iovec *iov,
size_t niov,
int *fds, size_t nfds,
int flags, Error **errp)
int coroutine_mixed_fn qio_channel_writev_full_all(QIOChannel *ioc,
const struct iovec *iov,
size_t niov,
int *fds, size_t nfds,
int flags, Error **errp)
{
int ret = -1;
struct iovec *local_iov = g_new(struct iovec, niov);
Expand Down Expand Up @@ -325,30 +325,30 @@ ssize_t qio_channel_write(QIOChannel *ioc,
}


int qio_channel_read_all_eof(QIOChannel *ioc,
char *buf,
size_t buflen,
Error **errp)
int coroutine_mixed_fn qio_channel_read_all_eof(QIOChannel *ioc,
char *buf,
size_t buflen,
Error **errp)
{
struct iovec iov = { .iov_base = buf, .iov_len = buflen };
return qio_channel_readv_all_eof(ioc, &iov, 1, errp);
}


int qio_channel_read_all(QIOChannel *ioc,
char *buf,
size_t buflen,
Error **errp)
int coroutine_mixed_fn qio_channel_read_all(QIOChannel *ioc,
char *buf,
size_t buflen,
Error **errp)
{
struct iovec iov = { .iov_base = buf, .iov_len = buflen };
return qio_channel_readv_all(ioc, &iov, 1, errp);
}


int qio_channel_write_all(QIOChannel *ioc,
const char *buf,
size_t buflen,
Error **errp)
int coroutine_mixed_fn qio_channel_write_all(QIOChannel *ioc,
const char *buf,
size_t buflen,
Error **errp)
{
struct iovec iov = { .iov_base = (char *)buf, .iov_len = buflen };
return qio_channel_writev_all(ioc, &iov, 1, errp);
Expand Down

0 comments on commit 1dd91b2

Please sign in to comment.