From patchwork Mon Oct 28 01:16:34 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: pingfan liu X-Patchwork-Id: 286390 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 2C92C2C00A8 for ; Mon, 28 Oct 2013 12:17:50 +1100 (EST) Received: from localhost ([::1]:39555 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VabSm-0006dk-18 for incoming@patchwork.ozlabs.org; Sun, 27 Oct 2013 21:17:48 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37436) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VabRV-0004yf-2y for qemu-devel@nongnu.org; Sun, 27 Oct 2013 21:16:37 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VabRM-00064a-GJ for qemu-devel@nongnu.org; Sun, 27 Oct 2013 21:16:28 -0400 Received: from mail-oa0-x22f.google.com ([2607:f8b0:4003:c02::22f]:55043) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VabRM-00064T-4F for qemu-devel@nongnu.org; Sun, 27 Oct 2013 21:16:20 -0400 Received: by mail-oa0-f47.google.com with SMTP id i1so2937101oag.20 for ; Sun, 27 Oct 2013 18:16:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=OcuSupnY61y9NLsvt6lxsVnXviLa1GsnUdjDCsnF3s8=; b=Wj1fo7tTTsyGJeKN4tFODz3+Z0xdbZR3uiKyhW3maRabr+jdEw0f+ESuCXp4dcn3Be z4jbzwuNwA+2XP87Kq3FziScxXIqU0F6FszDlDHpT9BTgOURK23Nvczj2jEtqhqdWTJL 2YT+CGFg7fhRNo2uenb+a4f/GXwStWuDNqnXEXf5E/wGfldW7gq9cZl/DqLGQ0FrRwpS 0FAoWDQlRtRL91iv5iHw6lfo0t66WqqgWvTo5K9CCFZvnC3pI1tosWyIvmdRjP7NZQUE TYEnfNO3eeUUZ7T4KH8VjqagliG8YVw/x+UMcerTpvacLwUl+CKqUFALv5husun9zqjt y+aA== X-Received: by 10.182.61.98 with SMTP id o2mr30195obr.57.1382922979093; Sun, 27 Oct 2013 18:16:19 -0700 (PDT) Received: from localhost ([202.108.130.138]) by mx.google.com with ESMTPSA id wd7sm23052154obc.3.2013.10.27.18.16.15 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Sun, 27 Oct 2013 18:16:17 -0700 (PDT) From: Liu Ping Fan To: qemu-devel@nongnu.org Date: Mon, 28 Oct 2013 09:16:34 +0800 Message-Id: <1382922994-16451-3-git-send-email-pingfank@linux.vnet.ibm.com> X-Mailer: git-send-email 1.8.1.4 In-Reply-To: <1382922994-16451-1-git-send-email-pingfank@linux.vnet.ibm.com> References: <1382922994-16451-1-git-send-email-pingfank@linux.vnet.ibm.com> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2607:f8b0:4003:c02::22f Cc: Paolo Bonzini , Stefan Hajnoczi , Jan Kiszka Subject: [Qemu-devel] [PATCH 2/2] slirp: make slirp event dispatch based on slirp instance X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Each slirp instance has its own GFuncs, so we can driver slirp by glib main loop. Signed-off-by: Liu Ping Fan --- For easing the review, This patch does not obey coding guide. Will fix it later --- main-loop.c | 6 --- net/slirp.c | 3 ++ slirp/TFX7d70.tmp | 0 slirp/libslirp.h | 7 ++- slirp/slirp.c | 133 ++++++++++++++++------------------------------------ slirp/slirp.h | 1 + slirp/socket.c | 1 - slirp/socket.h | 2 +- stubs/Makefile.objs | 1 - stubs/slirp.c | 11 ----- 10 files changed, 49 insertions(+), 116 deletions(-) create mode 100644 slirp/TFX7d70.tmp delete mode 100644 stubs/slirp.c diff --git a/main-loop.c b/main-loop.c index c3c9c28..374d26f 100644 --- a/main-loop.c +++ b/main-loop.c @@ -465,9 +465,6 @@ int main_loop_wait(int nonblocking) /* poll any events */ g_array_set_size(gpollfds, 0); /* reset for new iteration */ /* XXX: separate device handlers from system ones */ -#ifdef CONFIG_SLIRP - slirp_pollfds_fill(gpollfds, &timeout); -#endif qemu_iohandler_fill(gpollfds); if (timeout == UINT32_MAX) { @@ -482,9 +479,6 @@ int main_loop_wait(int nonblocking) ret = os_host_main_loop_wait(timeout_ns); qemu_iohandler_poll(gpollfds, ret); -#ifdef CONFIG_SLIRP - slirp_pollfds_poll(gpollfds, (ret < 0)); -#endif qemu_clock_run_all_timers(); diff --git a/net/slirp.c b/net/slirp.c index 124e953..2a21e16 100644 --- a/net/slirp.c +++ b/net/slirp.c @@ -35,6 +35,7 @@ #include "monitor/monitor.h" #include "qemu/sockets.h" #include "slirp/libslirp.h" +#include "slirp/slirp_gsource.h" #include "sysemu/char.h" static int get_str_sep(char *buf, int buf_size, const char **pp, int sep) @@ -76,6 +77,7 @@ typedef struct SlirpState { #ifndef _WIN32 char smb_dir[128]; #endif + SlirpGSource *slirp_src; } SlirpState; static struct slirp_config_str *slirp_configs; @@ -244,6 +246,7 @@ static int net_slirp_init(NetClientState *peer, const char *model, s->slirp = slirp_init(restricted, net, mask, host, vhostname, tftp_export, bootfile, dhcp, dns, dnssearch, s); + s->slirp_src = slirp_gsource_new(slirp_prepare, slirp_handler, s->slirp); QTAILQ_INSERT_TAIL(&slirp_stacks, s, entry); for (config = slirp_configs; config; config = config->next) { diff --git a/slirp/TFX7d70.tmp b/slirp/TFX7d70.tmp new file mode 100644 index 0000000..e69de29 diff --git a/slirp/libslirp.h b/slirp/libslirp.h index 5bdcbd5..bb0c537 100644 --- a/slirp/libslirp.h +++ b/slirp/libslirp.h @@ -16,10 +16,6 @@ Slirp *slirp_init(int restricted, struct in_addr vnetwork, void *opaque); void slirp_cleanup(Slirp *slirp); -void slirp_pollfds_fill(GArray *pollfds, uint32_t *timeout); - -void slirp_pollfds_poll(GArray *pollfds, int select_error); - void slirp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len); /* you must provide the following functions: */ @@ -39,5 +35,8 @@ void slirp_socket_recv(Slirp *slirp, struct in_addr guest_addr, int guest_port, const uint8_t *buf, int size); size_t slirp_socket_can_recv(Slirp *slirp, struct in_addr guest_addr, int guest_port); +gboolean slirp_prepare(GSource *source, gint *time); +gboolean slirp_handler(gpointer data); + #endif diff --git a/slirp/slirp.c b/slirp/slirp.c index bad8dad..6d57994 100644 --- a/slirp/slirp.c +++ b/slirp/slirp.c @@ -25,6 +25,7 @@ #include "qemu/timer.h" #include "sysemu/char.h" #include "slirp.h" +#include "slirp_gsource.h" #include "hw/hw.h" /* host loopback address */ @@ -262,46 +263,34 @@ void slirp_cleanup(Slirp *slirp) #define CONN_CANFSEND(so) (((so)->so_state & (SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED) #define CONN_CANFRCV(so) (((so)->so_state & (SS_FCANTRCVMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED) -static void slirp_update_timeout(uint32_t *timeout) +static void slirp_update_timeout(Slirp *slirp, gint *timeout) { - Slirp *slirp; - uint32_t t; + gint t = *timeout; if (*timeout <= TIMEOUT_FAST) { return; } - t = MIN(1000, *timeout); - - /* If we have tcp timeout with slirp, then we will fill @timeout with - * more precise value. - */ - QTAILQ_FOREACH(slirp, &slirp_instances, entry) { - if (slirp->time_fasttimo) { - *timeout = TIMEOUT_FAST; - return; - } - if (slirp->do_slowtimo) { - t = MIN(TIMEOUT_SLOW, t); - } + if (slirp->time_fasttimo) { + *timeout = TIMEOUT_FAST; + return; + } + if (slirp->do_slowtimo) { + t = MIN(TIMEOUT_SLOW, t); } *timeout = t; } -void slirp_pollfds_fill(GArray *pollfds, uint32_t *timeout) +gboolean slirp_prepare(GSource *source, gint *time) { - Slirp *slirp; + SlirpGSource *slirp_src = (SlirpGSource *)source; + Slirp *slirp = slirp_src->opaque; struct socket *so, *so_next; + u_int curtime; - if (QTAILQ_EMPTY(&slirp_instances)) { - return; - } - - /* - * First, TCP sockets - */ + curtime = qemu_clock_get_ms(QEMU_CLOCK_REALTIME); + slirp->curtime = curtime; - QTAILQ_FOREACH(slirp, &slirp_instances, entry) { /* * *_slowtimo needs calling if there are IP fragments * in the fragment queue, or there are TCP connections active @@ -315,7 +304,10 @@ void slirp_pollfds_fill(GArray *pollfds, uint32_t *timeout) so_next = so->so_next; - so->pollfds_idx = -1; + if (so->pollfd->fd == -1 && so->s != -1) { + so->pollfd->fd = so->s; + g_source_add_poll(source, so->pollfd); + } /* * See if we need a tcp_fasttimo @@ -337,12 +329,7 @@ void slirp_pollfds_fill(GArray *pollfds, uint32_t *timeout) * Set for reading sockets which are accepting */ if (so->so_state & SS_FACCEPTCONN) { - GPollFD pfd = { - .fd = so->s, - .events = G_IO_IN | G_IO_HUP | G_IO_ERR, - }; - so->pollfds_idx = pollfds->len; - g_array_append_val(pollfds, pfd); + so->pollfd->events = G_IO_IN | G_IO_HUP | G_IO_ERR; continue; } @@ -350,12 +337,7 @@ void slirp_pollfds_fill(GArray *pollfds, uint32_t *timeout) * Set for writing sockets which are connecting */ if (so->so_state & SS_ISFCONNECTING) { - GPollFD pfd = { - .fd = so->s, - .events = G_IO_OUT | G_IO_ERR, - }; - so->pollfds_idx = pollfds->len; - g_array_append_val(pollfds, pfd); + so->pollfd->events = G_IO_OUT | G_IO_ERR; continue; } @@ -377,12 +359,7 @@ void slirp_pollfds_fill(GArray *pollfds, uint32_t *timeout) } if (events) { - GPollFD pfd = { - .fd = so->s, - .events = events, - }; - so->pollfds_idx = pollfds->len; - g_array_append_val(pollfds, pfd); + so->pollfd->events = events; } } @@ -393,8 +370,6 @@ void slirp_pollfds_fill(GArray *pollfds, uint32_t *timeout) so = so_next) { so_next = so->so_next; - so->pollfds_idx = -1; - /* * See if it's timed out */ @@ -418,12 +393,7 @@ void slirp_pollfds_fill(GArray *pollfds, uint32_t *timeout) * (XXX <= 4 ?) */ if ((so->so_state & SS_ISFCONNECTED) && so->so_queued <= 4) { - GPollFD pfd = { - .fd = so->s, - .events = G_IO_IN | G_IO_HUP | G_IO_ERR, - }; - so->pollfds_idx = pollfds->len; - g_array_append_val(pollfds, pfd); + so->pollfd->events = G_IO_IN | G_IO_HUP | G_IO_ERR; } } @@ -434,8 +404,6 @@ void slirp_pollfds_fill(GArray *pollfds, uint32_t *timeout) so = so_next) { so_next = so->so_next; - so->pollfds_idx = -1; - /* * See if it's timed out */ @@ -449,31 +417,22 @@ void slirp_pollfds_fill(GArray *pollfds, uint32_t *timeout) } if (so->so_state & SS_ISFCONNECTED) { - GPollFD pfd = { - .fd = so->s, - .events = G_IO_IN | G_IO_HUP | G_IO_ERR, - }; - so->pollfds_idx = pollfds->len; - g_array_append_val(pollfds, pfd); + so->pollfd->events = G_IO_IN | G_IO_HUP | G_IO_ERR; } } - } - slirp_update_timeout(timeout); + + slirp_update_timeout(slirp, time); + return false; } -void slirp_pollfds_poll(GArray *pollfds, int select_error) +gboolean slirp_handler(gpointer data) { - Slirp *slirp; + SlirpGSource *src = data; + Slirp *slirp = src->opaque; struct socket *so, *so_next; int ret; + u_int curtime = qemu_clock_get_ms(QEMU_CLOCK_REALTIME); - if (QTAILQ_EMPTY(&slirp_instances)) { - return; - } - - curtime = qemu_clock_get_ms(QEMU_CLOCK_REALTIME); - - QTAILQ_FOREACH(slirp, &slirp_instances, entry) { /* * See if anything has timed out */ @@ -489,23 +448,17 @@ void slirp_pollfds_poll(GArray *pollfds, int select_error) slirp->last_slowtimo = curtime; } - /* - * Check sockets - */ - if (!select_error) { /* * Check TCP sockets */ for (so = slirp->tcb.so_next; so != &slirp->tcb; so = so_next) { - int revents; + int revents = 0; so_next = so->so_next; - revents = 0; - if (so->pollfds_idx != -1) { - revents = g_array_index(pollfds, GPollFD, - so->pollfds_idx).revents; + if (so->pollfd) { + revents = so->pollfd->revents; } if (so->so_state & SS_NOFDREF || so->s == -1) { @@ -629,14 +582,12 @@ void slirp_pollfds_poll(GArray *pollfds, int select_error) */ for (so = slirp->udb.so_next; so != &slirp->udb; so = so_next) { - int revents; + int revents = 0; so_next = so->so_next; - revents = 0; - if (so->pollfds_idx != -1) { - revents = g_array_index(pollfds, GPollFD, - so->pollfds_idx).revents; + if (so->pollfd) { + revents = so->pollfd->revents; } if (so->s != -1 && @@ -650,14 +601,13 @@ void slirp_pollfds_poll(GArray *pollfds, int select_error) */ for (so = slirp->icmp.so_next; so != &slirp->icmp; so = so_next) { - int revents; + int revents = 0; so_next = so->so_next; revents = 0; - if (so->pollfds_idx != -1) { - revents = g_array_index(pollfds, GPollFD, - so->pollfds_idx).revents; + if (so->pollfd) { + revents = so->pollfd->revents; } if (so->s != -1 && @@ -665,10 +615,9 @@ void slirp_pollfds_poll(GArray *pollfds, int select_error) icmp_receive(so); } } - } if_start(slirp); - } + return true; } static void arp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len) diff --git a/slirp/slirp.h b/slirp/slirp.h index e4a1bd4..ea08b4d 100644 --- a/slirp/slirp.h +++ b/slirp/slirp.h @@ -206,6 +206,7 @@ struct Slirp { u_int time_fasttimo; u_int last_slowtimo; bool do_slowtimo; + u_int curtime; /* virtual network configuration */ struct in_addr vnetwork_addr; diff --git a/slirp/socket.c b/slirp/socket.c index 37ac5cf..8b130e8 100644 --- a/slirp/socket.c +++ b/slirp/socket.c @@ -51,7 +51,6 @@ socreate(Slirp *slirp) so->so_state = SS_NOFDREF; so->s = -1; so->slirp = slirp; - so->pollfds_idx = -1; } return(so); } diff --git a/slirp/socket.h b/slirp/socket.h index 57e0407..373601f 100644 --- a/slirp/socket.h +++ b/slirp/socket.h @@ -20,7 +20,7 @@ struct socket { int s; /* The actual socket */ - int pollfds_idx; /* GPollFD GArray index */ + GPollFD *pollfd; Slirp *slirp; /* managing slirp instance */ diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs index df92fe5..130be9f 100644 --- a/stubs/Makefile.objs +++ b/stubs/Makefile.objs @@ -20,7 +20,6 @@ stub-obj-y += mon-set-error.o stub-obj-y += pci-drive-hot-add.o stub-obj-y += reset.o stub-obj-y += set-fd-handler.o -stub-obj-y += slirp.o stub-obj-y += sysbus.o stub-obj-y += uuid.o stub-obj-y += vm-stop.o diff --git a/stubs/slirp.c b/stubs/slirp.c deleted file mode 100644 index bd0ac7f..0000000 --- a/stubs/slirp.c +++ /dev/null @@ -1,11 +0,0 @@ -#include "qemu-common.h" -#include "slirp/slirp.h" - -void slirp_pollfds_fill(GArray *pollfds, uint32_t *timeout) -{ -} - -void slirp_pollfds_poll(GArray *pollfds, int select_error) -{ -} -