From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:41649) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TQEG8-00033U-Ik for qemu-devel@nongnu.org; Mon, 22 Oct 2012 05:25:26 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TQEG3-00077R-SO for qemu-devel@nongnu.org; Mon, 22 Oct 2012 05:25:20 -0400 Received: from e28smtp02.in.ibm.com ([122.248.162.2]:37617) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TQEG3-00077A-68 for qemu-devel@nongnu.org; Mon, 22 Oct 2012 05:25:15 -0400 Received: from /spool/local by e28smtp02.in.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Mon, 22 Oct 2012 14:55:11 +0530 Received: from d28av01.in.ibm.com (d28av01.in.ibm.com [9.184.220.63]) by d28relay02.in.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id q9M9OUSp37421148 for ; Mon, 22 Oct 2012 14:54:31 +0530 Received: from d28av01.in.ibm.com (loopback [127.0.0.1]) by d28av01.in.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id q9MEsMXU029255 for ; Mon, 22 Oct 2012 14:54:22 GMT From: Liu Ping Fan Date: Mon, 22 Oct 2012 17:23:58 +0800 Message-Id: <1350897839-29593-16-git-send-email-pingfank@linux.vnet.ibm.com> In-Reply-To: <1350897839-29593-1-git-send-email-pingfank@linux.vnet.ibm.com> References: <1350897839-29593-1-git-send-email-pingfank@linux.vnet.ibm.com> Subject: [Qemu-devel] [patch v4 15/16] e1000: introduce unmap() to fix unplug issue List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Stefan Hajnoczi , Marcelo Tosatti , Avi Kivity , Anthony Liguori , Jan Kiszka , Paolo Bonzini When device uninit(), we should ensure that it is not used by any subsystem. We can acheive this by two solution: 1.sync on big lock in uninit() function This is more easy, but it require that big lock can be recusive, because uninit() can be called by iothread or mmio-dispatch. 2.introduce unmap() as a sync point for all subsystem. This patch adpots solotion 2. Signed-off-by: Liu Ping Fan --- hw/e1000.c | 26 ++++++++++++++++++++++---- 1 files changed, 22 insertions(+), 4 deletions(-) diff --git a/hw/e1000.c b/hw/e1000.c index 0b4fce5..72c2324 100644 --- a/hw/e1000.c +++ b/hw/e1000.c @@ -168,7 +168,14 @@ set_phy_ctrl(E1000State *s, int index, uint16_t val) e1000_link_down(s); s->phy_reg[PHY_STATUS] &= ~MII_SR_AUTONEG_COMPLETE; DBGOUT(PHY, "Start link auto negotiation\n"); - qemu_mod_timer(s->autoneg_timer, qemu_get_clock_ms(vm_clock) + 500); + + qemu_mutex_unlock(&s->e1000_lock); + qemu_mutex_lock_iothread(); + if (DEVICE(s)->state < DEV_STATE_STOPPING) { + qemu_mod_timer(s->autoneg_timer, qemu_get_clock_ms(vm_clock) + 500); + } + qemu_mutex_unlock_iothread(); + qemu_mutex_lock(&s->e1000_lock); } } @@ -467,7 +474,9 @@ e1000_send_packet(E1000State *s, const uint8_t *buf, int size) } else { qemu_mutex_unlock(&s->e1000_lock); qemu_mutex_lock_iothread(); - qemu_send_packet(&s->nic->nc, buf, size); + if (DEVICE(s)->state < DEV_STATE_STOPPING) { + qemu_send_packet(&s->nic->nc, buf, size); + } qemu_mutex_unlock_iothread(); qemu_mutex_lock(&s->e1000_lock); } @@ -1221,6 +1230,16 @@ e1000_mmio_setup(E1000State *d) } static void +pci_e1000_unmap(PCIDevice *p) +{ + E1000State *d = DO_UPCAST(E1000State, dev, p); + + DEVICE(d)->state = DEV_STATE_STOPPING; + qemu_del_timer(d->autoneg_timer); + qemu_del_net_client(&d->nic->nc); +} + +static void e1000_cleanup(NetClientState *nc) { E1000State *s = DO_UPCAST(NICState, nc, nc)->opaque; @@ -1233,11 +1252,9 @@ pci_e1000_uninit(PCIDevice *dev) { E1000State *d = DO_UPCAST(E1000State, dev, dev); - qemu_del_timer(d->autoneg_timer); qemu_free_timer(d->autoneg_timer); memory_region_destroy(&d->mmio); memory_region_destroy(&d->io); - qemu_del_net_client(&d->nic->nc); } static NetClientInfo net_e1000_info = { @@ -1314,6 +1331,7 @@ static void e1000_class_init(ObjectClass *klass, void *data) k->init = pci_e1000_init; k->exit = pci_e1000_uninit; + k->unmap = pci_e1000_unmap; k->romfile = "pxe-e1000.rom"; k->vendor_id = PCI_VENDOR_ID_INTEL; k->device_id = E1000_DEVID; -- 1.7.4.4