From patchwork Thu Feb 21 12:54:51 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: pingfan liu X-Patchwork-Id: 222279 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 40AC62C008E for ; Thu, 21 Feb 2013 23:56:40 +1100 (EST) Received: from localhost ([::1]:38055 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1U8VhW-0001rt-DT for incoming@patchwork.ozlabs.org; Thu, 21 Feb 2013 07:56:38 -0500 Received: from eggs.gnu.org ([208.118.235.92]:59657) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1U8VhE-0001gB-Ie for qemu-devel@nongnu.org; Thu, 21 Feb 2013 07:56:23 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1U8Vh7-0002UV-Mh for qemu-devel@nongnu.org; Thu, 21 Feb 2013 07:56:20 -0500 Received: from mail-da0-f45.google.com ([209.85.210.45]:50547) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1U8Vh7-0002UC-EI for qemu-devel@nongnu.org; Thu, 21 Feb 2013 07:56:13 -0500 Received: by mail-da0-f45.google.com with SMTP id v40so608540dad.32 for ; Thu, 21 Feb 2013 04:56:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=x-received:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references; bh=eX0YdJNI1XkMmR4Jt+Ofv20JOJpMdF47C6UJ9Nl3kKM=; b=hSHiHvg48hVQlNPSUbowq1XUs1g66nmweRw0rTnQZmyxF+ojiGSbmtmFImk00X3Ayq 1PVFTLDwagTKLw3VLvBj1WmolR/P3GAd858BE7VzfF3oR1x/uztsm0DPxI57QY9Mtu8C CDA2bcYwGTG60Nh9q0A26T7gsv1v75P1ozcBCc7B18xq7HJO87hwUGLdcyczjB4s/HXM OevqIvWNRP7XzzgLBT4FZZkUaCpoa7xJO75fYsv/sfY/2n4v1erRAhEtx6uvBb1popoJ OY+WgxwEdbe+8vS1g+pefzgbsULH5v/B5dguXgRC56ZorFJyiuNk28PZwODH08/qiTMT 8tww== X-Received: by 10.66.232.97 with SMTP id tn1mr8012372pac.124.1361451372578; Thu, 21 Feb 2013 04:56:12 -0800 (PST) Received: from localhost ([222.128.155.155]) by mx.google.com with ESMTPS id pn9sm18474580pbb.22.2013.02.21.04.56.08 (version=TLSv1.1 cipher=RC4-SHA bits=128/128); Thu, 21 Feb 2013 04:56:11 -0800 (PST) From: Liu Ping Fan To: qemu-devel@nongnu.org Date: Thu, 21 Feb 2013 20:54:51 +0800 Message-Id: <1361451293-5181-8-git-send-email-qemulist@gmail.com> X-Mailer: git-send-email 1.7.4.4 In-Reply-To: <1361451293-5181-1-git-send-email-qemulist@gmail.com> References: <1361451293-5181-1-git-send-email-qemulist@gmail.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 209.85.210.45 Cc: Stefan Hajnoczi , Anthony Liguori Subject: [Qemu-devel] [PATCH 7/9] tap: make tap peer work on dedicated data-plane thread 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 From: Liu Ping Fan Signed-off-by: Liu Ping Fan --- hw/dataplane/virtio-net.c | 22 +++++++++++ hw/dataplane/virtio-net.h | 6 +++ include/net/tap.h | 6 +++ net/tap.c | 92 ++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 125 insertions(+), 1 deletions(-) diff --git a/hw/dataplane/virtio-net.c b/hw/dataplane/virtio-net.c index 9a1795d..c3aac08 100644 --- a/hw/dataplane/virtio-net.c +++ b/hw/dataplane/virtio-net.c @@ -246,6 +246,7 @@ static void rx_cb(EventHandler *handler, uint32_t events) { VirtIONet *n = handler->opaque; + tap_enable_read(n->nic->nc.peer); event_notifier_test_and_clear(handler->notifier); qemu_flush_queued_packets(&n->nic->nc); } @@ -388,6 +389,7 @@ void virtnet_dataplane_start(VirtIONet *n) event_poll_add(&t->polltbl, n->dp->rx_handler, rx_e, rx_cb); event_poll_add(&t->polltbl, n->dp->tx_handler, tx_e, tx_cb); + tap_create_epoll_event(n->nic->nc.peer); } void virtnet_dataplane_stop(VirtIONet *n) @@ -398,6 +400,7 @@ void virtnet_dataplane_stop(VirtIONet *n) event_poll_del_fd(&t->polltbl, event_notifier_get_fd(rx_e)); event_poll_del_fd(&t->polltbl, event_notifier_get_fd(tx_e)); + tap_del_epoll_event(n->nic->nc.peer); t->state = THREAD_EXIT; event_notifier_set(&t->e); @@ -420,3 +423,22 @@ void virtnet_dataplane_destroy(VirtIONet *n) g_free(n->dp->tx_handler); g_free(n->dp); } + +void thread_add_event(WorkThread *t, uint32_t event_type, EventHandler *handler) +{ + event_poll_add_fd(&t->polltbl, handler->fd, event_type, handler); + event_notifier_set(&t->e); +} + +void thread_del_event(WorkThread *t, EventHandler *handler) +{ + event_poll_del_fd(&t->polltbl, handler->fd); + event_notifier_set(&t->e); +} + +void thread_modify_event(WorkThread *t, uint32_t event_type, + EventHandler *handler) +{ + event_poll_modify_fd(&t->polltbl, handler->fd, event_type, handler); + event_notifier_set(&t->e); +} diff --git a/hw/dataplane/virtio-net.h b/hw/dataplane/virtio-net.h index e50b2de..5d6bd34 100644 --- a/hw/dataplane/virtio-net.h +++ b/hw/dataplane/virtio-net.h @@ -23,4 +23,10 @@ typedef struct WorkThread { } WorkThread; extern WorkThread virt_net_thread; + +void thread_add_event(WorkThread *t, uint32_t event_type, + EventHandler *handler); +void thread_del_event(WorkThread *t, EventHandler *handler); +void thread_modify_event(WorkThread *t, uint32_t event_type, + EventHandler *handler); #endif diff --git a/include/net/tap.h b/include/net/tap.h index bb7efb5..3f78d15 100644 --- a/include/net/tap.h +++ b/include/net/tap.h @@ -29,6 +29,12 @@ #include "qemu-common.h" #include "qapi-types.h" +#ifdef CONFIG_VIRTIO_NET_DATA_PLANE +int tap_create_epoll_event(NetClientState *nc); +int tap_del_epoll_event(NetClientState *nc); +void tap_enable_read(NetClientState *nc); +#endif + int tap_has_ufo(NetClientState *nc); int tap_has_vnet_hdr(NetClientState *nc); int tap_has_vnet_hdr_len(NetClientState *nc, int len); diff --git a/net/tap.c b/net/tap.c index eb40c42..b6bfed4 100644 --- a/net/tap.c +++ b/net/tap.c @@ -27,6 +27,7 @@ #include "config-host.h" +#include #include #include #include @@ -43,6 +44,7 @@ #include "net/tap.h" #include "hw/vhost_net.h" +#include "hw/dataplane/virtio-net.h" /* Maximum GSO packet size (64k) plus plenty of room for * the ethernet and virtio_net headers @@ -61,14 +63,22 @@ typedef struct TAPState { unsigned int has_ufo: 1; VHostNetState *vhost_net; unsigned host_vnet_hdr_len; + +#ifdef CONFIG_VIRTIO_NET_DATA_PLANE + EventHandler tap_evt; + uint32_t tap_events; + bool start; +#endif } TAPState; static int launch_script(const char *setup_script, const char *ifname, int fd); - +#ifndef CONFIG_VIRTIO_NET_DATA_PLANE static int tap_can_send(void *opaque); +#endif static void tap_send(void *opaque); static void tap_writable(void *opaque); +#ifndef CONFIG_VIRTIO_NET_DATA_PLANE static void tap_update_fd_handler(TAPState *s) { qemu_set_fd_handler2(s->fd, @@ -77,18 +87,96 @@ static void tap_update_fd_handler(TAPState *s) s->write_poll ? tap_writable : NULL, s); } +#endif static void tap_read_poll(TAPState *s, int enable) { +#ifdef CONFIG_VIRTIO_NET_DATA_PLANE + if (!s->start) { + return; + } + if (s->read_poll == !!enable) { + return; + } + + s->read_poll = !!enable; + if (enable) { + s->tap_events |= EPOLLIN; + } else { + s->tap_events &= ~EPOLLIN; + } + thread_modify_event(&virt_net_thread, s->tap_events, &s->tap_evt); +#else s->read_poll = !!enable; tap_update_fd_handler(s); +#endif } static void tap_write_poll(TAPState *s, int enable) { +#ifdef CONFIG_VIRTIO_NET_DATA_PLANE + if (!s->start) { + return; + } + if (s->write_poll == !!enable) { + return; + } + s->write_poll = !!enable; + if (enable) { + s->tap_events |= EPOLLOUT; + } else { + s->tap_events &= ~EPOLLOUT; + } + thread_modify_event(&virt_net_thread, s->tap_events, &s->tap_evt); +#else s->write_poll = !!enable; tap_update_fd_handler(s); +#endif +} + +#ifdef CONFIG_VIRTIO_NET_DATA_PLANE +static void tap_epoll_handle(EventHandler *handler, uint32_t events) +{ + if (events & EPOLLIN) { + tap_send(handler->opaque); + } + if (events & EPOLLOUT) { + tap_writable(handler->opaque); + } +} + +int tap_create_epoll_event(NetClientState *nc) +{ + TAPState *s = DO_UPCAST(TAPState, nc, nc); + + s->tap_evt.callback = tap_epoll_handle; + s->tap_evt.opaque = s; + s->tap_evt.notifier = NULL; + s->tap_evt.fd = s->fd; + + thread_add_event(&virt_net_thread, EPOLLIN|EPOLLOUT, &s->tap_evt); + s->start = true; + return 0; +} + +int tap_del_epoll_event(NetClientState *nc) +{ + TAPState *s = DO_UPCAST(TAPState, nc, nc); + + thread_del_event(&virt_net_thread, &s->tap_evt); + s->start = false; + return 0; +} + +void tap_enable_read(NetClientState *nc) +{ + TAPState *s = DO_UPCAST(TAPState, nc, nc); + + if (s->start) { + tap_read_poll(s, 1); + } } +#endif static void tap_writable(void *opaque) { @@ -169,12 +257,14 @@ static ssize_t tap_receive(NetClientState *nc, const uint8_t *buf, size_t size) return tap_write_packet(s, iov, 1); } +#ifndef CONFIG_VIRTIO_NET_DATA_PLANE static int tap_can_send(void *opaque) { TAPState *s = opaque; return qemu_can_send_packet(&s->nc); } +#endif #ifndef __sun__ ssize_t tap_read_packet(int tapfd, uint8_t *buf, int maxlen)