From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mx0a-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 40PSpd5NVLzF1S9 for ; Mon, 16 Apr 2018 09:46:49 +1000 (AEST) Received: from pps.filterd (m0098419.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w3FNhn7A008860 for ; Sun, 15 Apr 2018 19:46:46 -0400 Received: from e14.ny.us.ibm.com (e14.ny.us.ibm.com [129.33.205.204]) by mx0b-001b2d01.pphosted.com with ESMTP id 2hcdfjct46-1 (version=TLSv1.2 cipher=AES256-SHA256 bits=256 verify=NOT) for ; Sun, 15 Apr 2018 19:46:46 -0400 Received: from localhost by e14.ny.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Sun, 15 Apr 2018 19:46:46 -0400 Subject: Re: [PATCH] ibmvnic: Clear pending interrupt after device reset To: netdev@vger.kernel.org Cc: linuxppc-dev@lists.ozlabs.org, jallen@linux.vnet.ibm.com, nfont@linux.vnet.ibm.com, benh@kernel.crashing.org References: <1523834853-15448-1-git-send-email-tlfalcon@linux.vnet.ibm.com> From: Thomas Falcon Date: Sun, 15 Apr 2018 18:46:42 -0500 MIME-Version: 1.0 In-Reply-To: <1523834853-15448-1-git-send-email-tlfalcon@linux.vnet.ibm.com> Content-Type: text/plain; charset=utf-8 Message-Id: List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , On 04/15/2018 06:27 PM, Thomas Falcon wrote: > Due to a firmware bug, the hypervisor can send an interrupt to a > transmit or receive queue just prior to a partition migration, not > allowing the device enough time to handle it and send an EOI. When > the partition migrates, the interrupt is lost but an "EOI-pending" > flag for the interrupt line is still set in firmware. No further > interrupts will be sent until that flag is cleared, effectively > freezing that queue. To workaround this, the driver will disable the > hardware interrupt and send an H_EOI signal prior to re-enabling it. > This will flush the pending EOI and allow the driver to continue > operation. Excuse me, I misspelled the linuxppc-dev email address. Tom > Signed-off-by: Thomas Falcon > --- > drivers/net/ethernet/ibm/ibmvnic.c | 15 +++++++++++---- > 1 file changed, 11 insertions(+), 4 deletions(-) > > diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c > index f84a920..ef7995fc 100644 > --- a/drivers/net/ethernet/ibm/ibmvnic.c > +++ b/drivers/net/ethernet/ibm/ibmvnic.c > @@ -1034,16 +1034,14 @@ static int __ibmvnic_open(struct net_device *netdev) > netdev_dbg(netdev, "Enabling rx_scrq[%d] irq\n", i); > if (prev_state == VNIC_CLOSED) > enable_irq(adapter->rx_scrq[i]->irq); > - else > - enable_scrq_irq(adapter, adapter->rx_scrq[i]); > + enable_scrq_irq(adapter, adapter->rx_scrq[i]); > } > > for (i = 0; i < adapter->req_tx_queues; i++) { > netdev_dbg(netdev, "Enabling tx_scrq[%d] irq\n", i); > if (prev_state == VNIC_CLOSED) > enable_irq(adapter->tx_scrq[i]->irq); > - else > - enable_scrq_irq(adapter, adapter->tx_scrq[i]); > + enable_scrq_irq(adapter, adapter->tx_scrq[i]); > } > > rc = set_link_state(adapter, IBMVNIC_LOGICAL_LNK_UP); > @@ -1184,6 +1182,7 @@ static void ibmvnic_disable_irqs(struct ibmvnic_adapter *adapter) > if (adapter->tx_scrq[i]->irq) { > netdev_dbg(netdev, > "Disabling tx_scrq[%d] irq\n", i); > + disable_scrq_irq(adapter, adapter->tx_scrq[i]); > disable_irq(adapter->tx_scrq[i]->irq); > } > } > @@ -1193,6 +1192,7 @@ static void ibmvnic_disable_irqs(struct ibmvnic_adapter *adapter) > if (adapter->rx_scrq[i]->irq) { > netdev_dbg(netdev, > "Disabling rx_scrq[%d] irq\n", i); > + disable_scrq_irq(adapter, adapter->rx_scrq[i]); > disable_irq(adapter->rx_scrq[i]->irq); > } > } > @@ -2601,12 +2601,19 @@ static int enable_scrq_irq(struct ibmvnic_adapter *adapter, > { > struct device *dev = &adapter->vdev->dev; > unsigned long rc; > + u64 val; > > if (scrq->hw_irq > 0x100000000ULL) { > dev_err(dev, "bad hw_irq = %lx\n", scrq->hw_irq); > return 1; > } > > + val = (0xff000000) | scrq->hw_irq; > + rc = plpar_hcall_norets(H_EOI, val); > + if (rc) > + dev_err(dev, "H_EOI FAILED irq 0x%llx. rc=%ld\n", > + val, rc); > + > rc = plpar_hcall_norets(H_VIOCTL, adapter->vdev->unit_address, > H_ENABLE_VIO_INTERRUPT, scrq->hw_irq, 0, 0); > if (rc)