aboutsummaryrefslogtreecommitdiff
path: root/io
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2022-12-16 12:47:58 +0100
committerPaolo Bonzini <pbonzini@redhat.com>2023-04-20 11:17:35 +0200
commit1dd91b22a620616cad08bee7efc29280121ff0da (patch)
tree6cf38ed8ffeba6f3d8b9821eda8fe758924cd6d1 /io
parentcf9d4e68d7bcd333d59d2f3ff876b86dec00281a (diff)
downloadqemu-1dd91b22a620616cad08bee7efc29280121ff0da.zip
qemu-1dd91b22a620616cad08bee7efc29280121ff0da.tar.gz
qemu-1dd91b22a620616cad08bee7efc29280121ff0da.tar.bz2
io: mark mixed functions that can suspend
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>
Diffstat (limited to 'io')
-rw-r--r--io/channel.c78
1 files changed, 39 insertions, 39 deletions
diff --git a/io/channel.c b/io/channel.c
index a8c7f11..375a130 100644
--- a/io/channel.c
+++ b/io/channel.c
@@ -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);
@@ -215,11 +215,11 @@ next_iter:
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);
@@ -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);
@@ -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);