From effd5afd9438ae9e6994aa03de68b4138749ca8f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sun, 25 Jan 2015 21:44:13 +0800 Subject: [PATCH] 3.14-stable patches added patches: net-ethernet-cpsw-fix-hangs-with-interrupts.patch storvsc-ring-buffer-failures-may-result-in-i-o-freeze.patch --- ...ernet-cpsw-fix-hangs-with-interrupts.patch | 119 ++++++++++++++++++ queue-3.14/series | 2 + ...er-failures-may-result-in-i-o-freeze.patch | 42 +++++++ 3 files changed, 163 insertions(+) create mode 100644 queue-3.14/net-ethernet-cpsw-fix-hangs-with-interrupts.patch create mode 100644 queue-3.14/storvsc-ring-buffer-failures-may-result-in-i-o-freeze.patch diff --git a/queue-3.14/net-ethernet-cpsw-fix-hangs-with-interrupts.patch b/queue-3.14/net-ethernet-cpsw-fix-hangs-with-interrupts.patch new file mode 100644 index 00000000000..1a779c960e6 --- /dev/null +++ b/queue-3.14/net-ethernet-cpsw-fix-hangs-with-interrupts.patch @@ -0,0 +1,119 @@ +From 7ce67a38f799d1fb332f672b117efbadedaa5352 Mon Sep 17 00:00:00 2001 +From: Felipe Balbi +Date: Fri, 2 Jan 2015 16:15:59 -0600 +Subject: net: ethernet: cpsw: fix hangs with interrupts + +From: Felipe Balbi + +commit 7ce67a38f799d1fb332f672b117efbadedaa5352 upstream. + +The CPSW IP implements pulse-signaled interrupts. Due to +that we must write a correct, pre-defined value to the +CPDMA_MACEOIVECTOR register so the controller generates +a pulse on the correct IRQ line to signal the End Of +Interrupt. + +The way the driver is written today, all four IRQ lines +are requested using the same IRQ handler and, because of +that, we could fall into situations where a TX IRQ fires +but we tell the controller that we ended an RX IRQ (or +vice-versa). This situation triggers an IRQ storm on the +reserved IRQ 127 of INTC which will in turn call ack_bad_irq() +which will, then, print a ton of: + + unexpected IRQ trap at vector 00 + +In order to fix the problem, we are moving all calls to +cpdma_ctlr_eoi() inside the IRQ handler and making sure +we *always* write the correct value to the CPDMA_MACEOIVECTOR +register. Note that the algorithm assumes that IRQ numbers and +value-to-be-written-to-EOI are proportional, meaning that a +write of value 0 would trigger an EOI pulse for the RX_THRESHOLD +Interrupt and that's the IRQ number sitting in the 0-th index +of our irqs_table array. + +This, however, is safe at least for current implementations of +CPSW so we will refrain from making the check smarter (and, as +a side-effect, slower) until we actually have a platform where +IRQ lines are swapped. + +This patch has been tested for several days with AM335x- and +AM437x-based platforms. AM57x was left out because there are +still pending patches to enable ethernet in mainline for that +platform. A read of the TRM confirms the statement on previous +paragraph. + +Reported-by: Yegor Yefremov +Fixes: 510a1e7 (drivers: net: davinci_cpdma: acknowledge interrupt properly) +Signed-off-by: Felipe Balbi +Acked-by: Tony Lindgren +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/ethernet/ti/cpsw.c | 19 ++++++++----------- + 1 file changed, 8 insertions(+), 11 deletions(-) + +--- a/drivers/net/ethernet/ti/cpsw.c ++++ b/drivers/net/ethernet/ti/cpsw.c +@@ -716,6 +716,14 @@ static void cpsw_rx_handler(void *token, + static irqreturn_t cpsw_interrupt(int irq, void *dev_id) + { + struct cpsw_priv *priv = dev_id; ++ int value = irq - priv->irqs_table[0]; ++ ++ /* NOTICE: Ending IRQ here. The trick with the 'value' variable above ++ * is to make sure we will always write the correct value to the EOI ++ * register. Namely 0 for RX_THRESH Interrupt, 1 for RX Interrupt, 2 ++ * for TX Interrupt and 3 for MISC Interrupt. ++ */ ++ cpdma_ctlr_eoi(priv->dma, value); + + cpsw_intr_disable(priv); + if (priv->irq_enabled == true) { +@@ -745,8 +753,6 @@ static int cpsw_poll(struct napi_struct + int num_tx, num_rx; + + num_tx = cpdma_chan_process(priv->txch, 128); +- if (num_tx) +- cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_TX); + + num_rx = cpdma_chan_process(priv->rxch, budget); + if (num_rx < budget) { +@@ -754,7 +760,6 @@ static int cpsw_poll(struct napi_struct + + napi_complete(napi); + cpsw_intr_enable(priv); +- cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_RX); + prim_cpsw = cpsw_get_slave_priv(priv, 0); + if (prim_cpsw->irq_enabled == false) { + prim_cpsw->irq_enabled = true; +@@ -1265,8 +1270,6 @@ static int cpsw_ndo_open(struct net_devi + napi_enable(&priv->napi); + cpdma_ctlr_start(priv->dma); + cpsw_intr_enable(priv); +- cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_RX); +- cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_TX); + + if (priv->data.dual_emac) + priv->slaves[priv->emac_port].open_stat = true; +@@ -1512,9 +1515,6 @@ static void cpsw_ndo_tx_timeout(struct n + cpdma_chan_start(priv->txch); + cpdma_ctlr_int_ctrl(priv->dma, true); + cpsw_intr_enable(priv); +- cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_RX); +- cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_TX); +- + } + + static int cpsw_ndo_set_mac_address(struct net_device *ndev, void *p) +@@ -1560,9 +1560,6 @@ static void cpsw_ndo_poll_controller(str + cpsw_interrupt(ndev->irq, priv); + cpdma_ctlr_int_ctrl(priv->dma, true); + cpsw_intr_enable(priv); +- cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_RX); +- cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_TX); +- + } + #endif + diff --git a/queue-3.14/series b/queue-3.14/series index 5004461c603..f163b4fb0b4 100644 --- a/queue-3.14/series +++ b/queue-3.14/series @@ -40,3 +40,5 @@ clk-samsung-fix-double-add-of-syscore-ops-after-driver-rebind.patch clk-really-fix-deadlock-with-mmap_sem.patch clk-don-t-try-to-use-a-struct-clk-after-it-could-have-been-freed.patch parisc-fix-out-of-register-compiler-error-in-ldcw-inline-assembler-function.patch +storvsc-ring-buffer-failures-may-result-in-i-o-freeze.patch +net-ethernet-cpsw-fix-hangs-with-interrupts.patch diff --git a/queue-3.14/storvsc-ring-buffer-failures-may-result-in-i-o-freeze.patch b/queue-3.14/storvsc-ring-buffer-failures-may-result-in-i-o-freeze.patch new file mode 100644 index 00000000000..7b690e219e2 --- /dev/null +++ b/queue-3.14/storvsc-ring-buffer-failures-may-result-in-i-o-freeze.patch @@ -0,0 +1,42 @@ +From e86fb5e8ab95f10ec5f2e9430119d5d35020c951 Mon Sep 17 00:00:00 2001 +From: Long Li +Date: Fri, 5 Dec 2014 19:38:18 -0800 +Subject: storvsc: ring buffer failures may result in I/O freeze + +From: Long Li + +commit e86fb5e8ab95f10ec5f2e9430119d5d35020c951 upstream. + +When ring buffer returns an error indicating retry, storvsc may not +return a proper error code to SCSI when bounce buffer is not used. +This has introduced I/O freeze on RAID running atop storvsc devices. +This patch fixes it by always returning a proper error code. + +Signed-off-by: Long Li +Reviewed-by: K. Y. Srinivasan +Signed-off-by: Christoph Hellwig +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/storvsc_drv.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +--- a/drivers/scsi/storvsc_drv.c ++++ b/drivers/scsi/storvsc_drv.c +@@ -1690,13 +1690,12 @@ static int storvsc_queuecommand(struct S + if (ret == -EAGAIN) { + /* no more space */ + +- if (cmd_request->bounce_sgl_count) { ++ if (cmd_request->bounce_sgl_count) + destroy_bounce_buffer(cmd_request->bounce_sgl, + cmd_request->bounce_sgl_count); + +- ret = SCSI_MLQUEUE_DEVICE_BUSY; +- goto queue_error; +- } ++ ret = SCSI_MLQUEUE_DEVICE_BUSY; ++ goto queue_error; + } + + return 0; -- 2.47.3