aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/rsxx
diff options
context:
space:
mode:
authorPhilip J Kelleher <pjk1939@linux.vnet.ibm.com>2013-10-18 18:11:46 -0400
committerJens Axboe <axboe@kernel.dk>2013-11-08 11:10:29 -0500
commite35f38bf73b6c9ec9521d9deb94198a419692db5 (patch)
tree4ecd863d83eeb7e9752312f8757f5c6e03f4ea06 /drivers/block/rsxx
parent35f47ef1a1f069cd2f346314fb8212bb49571eac (diff)
rsxx: Disallow discards from being unmapped.
This patch fixes a bug in which discards were always calling pci_unmap_page. Discards should never call the pci_unmap_page function call because they are never mapped. This caused a race condition on PowerPC systems when issuing discards, writes, and reads all at the same time. The pci_map_page function would eventually map logical address 0 for a read or write. Discards are always assigned a DMA address of 0 because they are never mapped. So if pci_map_page mapped address 0 for a DMA and a discard was "unmapped" then the address would be freed and would cause an EEH event to occur when Hardware accesses the address. This was injected/uncovered in commit: b347f9cf0bc8d42ee95ba1d3837fd93045ab336b The pci_dma_mapping_error function declares -1 a DMA_ERROR not 0 like initially thought So before we would never unmap discards because they were considered NULL. This patch should fall on top of commit id: fc1967bb08a6184ed44ef990e1dd4389901b809c Also, the driver version is being up dated. Signed-off-by: Philip J Kelleher <pjk1939@linux.vnet.ibm.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'drivers/block/rsxx')
-rw-r--r--drivers/block/rsxx/dma.c27
-rw-r--r--drivers/block/rsxx/rsxx_priv.h2
2 files changed, 17 insertions, 12 deletions
diff --git a/drivers/block/rsxx/dma.c b/drivers/block/rsxx/dma.c
index 4103601ae675..fc88ba3e1bd2 100644
--- a/drivers/block/rsxx/dma.c
+++ b/drivers/block/rsxx/dma.c
@@ -223,12 +223,14 @@ static void dma_intr_coal_auto_tune(struct rsxx_cardinfo *card)
223/*----------------- RSXX DMA Handling -------------------*/ 223/*----------------- RSXX DMA Handling -------------------*/
224static void rsxx_free_dma(struct rsxx_dma_ctrl *ctrl, struct rsxx_dma *dma) 224static void rsxx_free_dma(struct rsxx_dma_ctrl *ctrl, struct rsxx_dma *dma)
225{ 225{
226 if (!pci_dma_mapping_error(ctrl->card->dev, dma->dma_addr)) { 226 if (dma->cmd != HW_CMD_BLK_DISCARD) {
227 pci_unmap_page(ctrl->card->dev, dma->dma_addr, 227 if (!pci_dma_mapping_error(ctrl->card->dev, dma->dma_addr)) {
228 get_dma_size(dma), 228 pci_unmap_page(ctrl->card->dev, dma->dma_addr,
229 dma->cmd == HW_CMD_BLK_WRITE ? 229 get_dma_size(dma),
230 PCI_DMA_TODEVICE : 230 dma->cmd == HW_CMD_BLK_WRITE ?
231 PCI_DMA_FROMDEVICE); 231 PCI_DMA_TODEVICE :
232 PCI_DMA_FROMDEVICE);
233 }
232 } 234 }
233 235
234 kmem_cache_free(rsxx_dma_pool, dma); 236 kmem_cache_free(rsxx_dma_pool, dma);
@@ -1057,11 +1059,14 @@ int rsxx_eeh_save_issued_dmas(struct rsxx_cardinfo *card)
1057 else 1059 else
1058 card->ctrl[i].stats.reads_issued--; 1060 card->ctrl[i].stats.reads_issued--;
1059 1061
1060 pci_unmap_page(card->dev, dma->dma_addr, 1062 if (dma->cmd != HW_CMD_BLK_DISCARD) {
1061 get_dma_size(dma), 1063 pci_unmap_page(card->dev, dma->dma_addr,
1062 dma->cmd == HW_CMD_BLK_WRITE ? 1064 get_dma_size(dma),
1063 PCI_DMA_TODEVICE : 1065 dma->cmd == HW_CMD_BLK_WRITE ?
1064 PCI_DMA_FROMDEVICE); 1066 PCI_DMA_TODEVICE :
1067 PCI_DMA_FROMDEVICE);
1068 }
1069
1065 list_add_tail(&dma->list, &issued_dmas[i]); 1070 list_add_tail(&dma->list, &issued_dmas[i]);
1066 push_tracker(card->ctrl[i].trackers, j); 1071 push_tracker(card->ctrl[i].trackers, j);
1067 cnt++; 1072 cnt++;
diff --git a/drivers/block/rsxx/rsxx_priv.h b/drivers/block/rsxx/rsxx_priv.h
index 913740e53d31..23fa05630fef 100644
--- a/drivers/block/rsxx/rsxx_priv.h
+++ b/drivers/block/rsxx/rsxx_priv.h
@@ -52,7 +52,7 @@ struct proc_cmd;
52#define RS70_PCI_REV_SUPPORTED 4 52#define RS70_PCI_REV_SUPPORTED 4
53 53
54#define DRIVER_NAME "rsxx" 54#define DRIVER_NAME "rsxx"
55#define DRIVER_VERSION "4.0.1.2498" 55#define DRIVER_VERSION "4.0.2.2510"
56 56
57/* Block size is 4096 */ 57/* Block size is 4096 */
58#define RSXX_HW_BLK_SHIFT 12 58#define RSXX_HW_BLK_SHIFT 12