From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:54807) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TQEFW-0002ro-T3 for qemu-devel@nongnu.org; Mon, 22 Oct 2012 05:24:46 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TQEFL-0006hG-1G for qemu-devel@nongnu.org; Mon, 22 Oct 2012 05:24:42 -0400 Received: from e28smtp04.in.ibm.com ([122.248.162.4]:39406) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TQEFK-0006gs-DM for qemu-devel@nongnu.org; Mon, 22 Oct 2012 05:24:30 -0400 Received: from /spool/local by e28smtp04.in.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Mon, 22 Oct 2012 14:54:28 +0530 Received: from d28av01.in.ibm.com (d28av01.in.ibm.com [9.184.220.63]) by d28relay05.in.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id q9M9OQEH1573244 for ; Mon, 22 Oct 2012 14:54:26 +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 q9MEsHEC028774 for ; Mon, 22 Oct 2012 14:54:18 GMT From: Liu Ping Fan Date: Mon, 22 Oct 2012 17:23:55 +0800 Message-Id: <1350897839-29593-13-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 12/16] e1000: apply fine lock on e1000 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 Use local lock to protect e1000. When calling the system function, dropping the fine lock before acquiring the big lock. This will introduce broken device state, which need extra effort to fix. Signed-off-by: Liu Ping Fan --- hw/e1000.c | 24 +++++++++++++++++++++++- 1 files changed, 23 insertions(+), 1 deletions(-) diff --git a/hw/e1000.c b/hw/e1000.c index ae8a6c5..5eddab5 100644 --- a/hw/e1000.c +++ b/hw/e1000.c @@ -85,6 +85,7 @@ typedef struct E1000State_st { NICConf conf; MemoryRegion mmio; MemoryRegion io; + QemuMutex e1000_lock; uint32_t mac_reg[0x8000]; uint16_t phy_reg[0x20]; @@ -223,13 +224,27 @@ static const uint32_t mac_reg_init[] = { static void set_interrupt_cause(E1000State *s, int index, uint32_t val) { + QemuThread *t; + if (val && (E1000_DEVID >= E1000_DEV_ID_82547EI_MOBILE)) { /* Only for 8257x */ val |= E1000_ICR_INT_ASSERTED; } s->mac_reg[ICR] = val; s->mac_reg[ICS] = val; - qemu_set_irq(s->dev.irq[0], (s->mac_reg[IMS] & s->mac_reg[ICR]) != 0); + + t = pthread_getspecific(qemu_thread_key); + if (t->context_type == 1) { + qemu_mutex_unlock(&s->e1000_lock); + qemu_mutex_lock_iothread(); + } + if (DEVICE(s)->state < DEV_STATE_STOPPING) { + qemu_set_irq(s->dev.irq[0], (s->mac_reg[IMS] & s->mac_reg[ICR]) != 0); + } + if (t->context_type == 1) { + qemu_mutex_unlock_iothread(); + qemu_mutex_lock(&s->e1000_lock); + } } static void @@ -268,6 +283,7 @@ static void e1000_reset(void *opaque) E1000State *d = opaque; qemu_del_timer(d->autoneg_timer); + memset(d->phy_reg, 0, sizeof d->phy_reg); memmove(d->phy_reg, phy_reg_init, sizeof phy_reg_init); memset(d->mac_reg, 0, sizeof d->mac_reg); @@ -448,7 +464,11 @@ e1000_send_packet(E1000State *s, const uint8_t *buf, int size) if (s->phy_reg[PHY_CTRL] & MII_CR_LOOPBACK) { s->nic->nc.info->receive(&s->nic->nc, buf, size); } else { + qemu_mutex_unlock(&s->e1000_lock); + qemu_mutex_lock_iothread(); qemu_send_packet(&s->nic->nc, buf, size); + qemu_mutex_unlock_iothread(); + qemu_mutex_lock(&s->e1000_lock); } } @@ -1221,6 +1241,8 @@ static int pci_e1000_init(PCIDevice *pci_dev) int i; uint8_t *macaddr; + qemu_mutex_init(&d->e1000_lock); + pci_conf = d->dev.config; /* TODO: RST# value should be 0, PCI spec 6.2.4 */ -- 1.7.4.4