From: Liu Ping Fan <pingf...@linux.vnet.ibm.com> Forward packet to other hub ports by their AioContext.
Signed-off-by: Liu Ping Fan <pingf...@linux.vnet.ibm.com> --- hw/qdev-properties-system.c | 1 + include/block/aio.h | 1 + include/net/net.h | 5 +++++ include/net/queue.h | 14 ++++++++++++++ main-loop.c | 5 +++++ net/hub.c | 33 ++++++++++++++++++++++++++++++--- net/net.c | 1 + net/queue.c | 4 ++-- 8 files changed, 59 insertions(+), 5 deletions(-) diff --git a/hw/qdev-properties-system.c b/hw/qdev-properties-system.c index ce3af22..587a335 100644 --- a/hw/qdev-properties-system.c +++ b/hw/qdev-properties-system.c @@ -307,6 +307,7 @@ static void set_vlan(Object *obj, Visitor *v, void *opaque, name, prop->info->name); return; } + hubport->info->bind_ctx(hubport, qemu_get_aio_context()); *ptr = hubport; } diff --git a/include/block/aio.h b/include/block/aio.h index 5b54d38..bcb5126 100644 --- a/include/block/aio.h +++ b/include/block/aio.h @@ -229,6 +229,7 @@ bool qemu_aio_wait(void); void qemu_aio_set_event_notifier(EventNotifier *notifier, EventNotifierHandler *io_read, AioFlushEventNotifierHandler *io_flush); +AioContext *qemu_get_aio_context(void); #ifdef CONFIG_POSIX void qemu_aio_set_fd_handler(int fd, diff --git a/include/net/net.h b/include/net/net.h index cb049a1..9c2b357 100644 --- a/include/net/net.h +++ b/include/net/net.h @@ -8,6 +8,9 @@ #include "net/queue.h" #include "migration/vmstate.h" #include "qapi-types.h" +#include "qemu/thread.h" +#include "block/aio.h" + #define MAX_QUEUE_NUM 1024 @@ -44,6 +47,7 @@ typedef ssize_t (NetReceiveIOV)(NetClientState *, const struct iovec *, int); typedef void (NetCleanup) (NetClientState *); typedef void (LinkStatusChanged)(NetClientState *); typedef void (NetClientDestructor)(NetClientState *); +typedef void (NetClientBindCtx)(NetClientState *, AioContext *); typedef struct NetClientInfo { NetClientOptionsKind type; @@ -55,6 +59,7 @@ typedef struct NetClientInfo { NetCleanup *cleanup; LinkStatusChanged *link_status_changed; NetPoll *poll; + NetClientBindCtx *bind_ctx; } NetClientInfo; struct NetClientState { diff --git a/include/net/queue.h b/include/net/queue.h index fc02b33..f60e57f 100644 --- a/include/net/queue.h +++ b/include/net/queue.h @@ -38,6 +38,20 @@ NetQueue *qemu_new_net_queue(void *opaque); void qemu_del_net_queue(NetQueue *queue); +void qemu_net_queue_append(NetQueue *queue, + NetClientState *sender, + unsigned flags, + const uint8_t *buf, + size_t size, + NetPacketSent *sent_cb); + +void qemu_net_queue_append_iov(NetQueue *queue, + NetClientState *sender, + unsigned flags, + const struct iovec *iov, + int iovcnt, + NetPacketSent *sent_cb); + ssize_t qemu_net_queue_send(NetQueue *queue, NetClientState *sender, unsigned flags, diff --git a/main-loop.c b/main-loop.c index 8c9b58c..eb80ff3 100644 --- a/main-loop.c +++ b/main-loop.c @@ -109,6 +109,11 @@ static int qemu_signal_init(void) static AioContext *qemu_aio_context; +AioContext *qemu_get_aio_context(void) +{ + return qemu_aio_context; +} + void qemu_notify_event(void) { if (!qemu_aio_context) { diff --git a/net/hub.c b/net/hub.c index df32074..73c1f26 100644 --- a/net/hub.c +++ b/net/hub.c @@ -31,6 +31,8 @@ typedef struct NetHubPort { QLIST_ENTRY(NetHubPort) next; NetHub *hub; int id; + EventNotifier e; + AioContext *ctx; } NetHubPort; struct NetHub { @@ -52,11 +54,20 @@ static ssize_t net_hub_receive(NetHub *hub, NetHubPort *source_port, continue; } - qemu_send_packet(&port->nc, buf, len); + qemu_net_queue_append(port->nc.peer->send_queue, &port->nc, + QEMU_NET_PACKET_FLAG_NONE, buf, len, NULL); + event_notifier_set(&port->e); } return len; } +static void hub_port_deliver_packet(void *opaque) +{ + NetHubPort *port = (NetHubPort *)opaque; + + qemu_net_queue_flush(port->nc.peer->send_queue); +} + static ssize_t net_hub_receive_iov(NetHub *hub, NetHubPort *source_port, const struct iovec *iov, int iovcnt) { @@ -68,7 +79,9 @@ static ssize_t net_hub_receive_iov(NetHub *hub, NetHubPort *source_port, continue; } - qemu_sendv_packet(&port->nc, iov, iovcnt); + qemu_net_queue_append_iov(port->nc.peer->send_queue, &port->nc, + QEMU_NET_PACKET_FLAG_NONE, iov, iovcnt, NULL); + event_notifier_set(&port->e); } return len; } @@ -126,9 +139,22 @@ static void net_hub_port_cleanup(NetClientState *nc) { NetHubPort *port = DO_UPCAST(NetHubPort, nc, nc); + if (port->ctx) { + aio_set_fd_handler(port->ctx, event_notifier_get_fd(&port->e), + NULL, NULL, NULL, NULL); + } QLIST_REMOVE(port, next); } +static void net_hub_port_bind_ctx(NetClientState *nc, AioContext *ctx) +{ + NetHubPort *port = DO_UPCAST(NetHubPort, nc, nc); + + port->ctx = ctx; + aio_set_fd_handler(ctx, event_notifier_get_fd(&port->e), + hub_port_deliver_packet, NULL, NULL, port); +} + static NetClientInfo net_hub_port_info = { .type = NET_CLIENT_OPTIONS_KIND_HUBPORT, .size = sizeof(NetHubPort), @@ -136,6 +162,7 @@ static NetClientInfo net_hub_port_info = { .receive = net_hub_port_receive, .receive_iov = net_hub_port_receive_iov, .cleanup = net_hub_port_cleanup, + .bind_ctx = net_hub_port_bind_ctx, }; static NetHubPort *net_hub_port_new(NetHub *hub, const char *name) @@ -155,7 +182,7 @@ static NetHubPort *net_hub_port_new(NetHub *hub, const char *name) port = DO_UPCAST(NetHubPort, nc, nc); port->id = id; port->hub = hub; - + event_notifier_init(&port->e, 0); QLIST_INSERT_HEAD(&hub->ports, port, next); return port; diff --git a/net/net.c b/net/net.c index f3d67f8..104c5b2 100644 --- a/net/net.c +++ b/net/net.c @@ -781,6 +781,7 @@ static int net_client_init1(const void *object, int is_netdev, Error **errp) (opts->kind != NET_CLIENT_OPTIONS_KIND_NIC || !opts->nic->has_netdev)) { peer = net_hub_add_port(u.net->has_vlan ? u.net->vlan : 0, NULL); + peer->info->bind_ctx(peer, qemu_get_aio_context()); } if (net_client_init_fun[opts->kind](opts, name, peer) < 0) { diff --git a/net/queue.c b/net/queue.c index 859d02a..67959f8 100644 --- a/net/queue.c +++ b/net/queue.c @@ -87,7 +87,7 @@ void qemu_del_net_queue(NetQueue *queue) g_free(queue); } -static void qemu_net_queue_append(NetQueue *queue, +void qemu_net_queue_append(NetQueue *queue, NetClientState *sender, unsigned flags, const uint8_t *buf, @@ -110,7 +110,7 @@ static void qemu_net_queue_append(NetQueue *queue, QTAILQ_INSERT_TAIL(&queue->packets, packet, entry); } -static void qemu_net_queue_append_iov(NetQueue *queue, +void qemu_net_queue_append_iov(NetQueue *queue, NetClientState *sender, unsigned flags, const struct iovec *iov, -- 1.7.4.4