提交 e35f38bf 编写于 作者: P Philip J Kelleher 提交者: Jens Axboe

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: NPhilip J Kelleher <pjk1939@linux.vnet.ibm.com>
Signed-off-by: NJens Axboe <axboe@kernel.dk>
上级 35f47ef1
...@@ -223,12 +223,14 @@ static void dma_intr_coal_auto_tune(struct rsxx_cardinfo *card) ...@@ -223,12 +223,14 @@ static void dma_intr_coal_auto_tune(struct rsxx_cardinfo *card)
/*----------------- RSXX DMA Handling -------------------*/ /*----------------- RSXX DMA Handling -------------------*/
static void rsxx_free_dma(struct rsxx_dma_ctrl *ctrl, struct rsxx_dma *dma) static void rsxx_free_dma(struct rsxx_dma_ctrl *ctrl, struct rsxx_dma *dma)
{ {
if (!pci_dma_mapping_error(ctrl->card->dev, dma->dma_addr)) { if (dma->cmd != HW_CMD_BLK_DISCARD) {
pci_unmap_page(ctrl->card->dev, dma->dma_addr, if (!pci_dma_mapping_error(ctrl->card->dev, dma->dma_addr)) {
get_dma_size(dma), pci_unmap_page(ctrl->card->dev, dma->dma_addr,
dma->cmd == HW_CMD_BLK_WRITE ? get_dma_size(dma),
PCI_DMA_TODEVICE : dma->cmd == HW_CMD_BLK_WRITE ?
PCI_DMA_FROMDEVICE); PCI_DMA_TODEVICE :
PCI_DMA_FROMDEVICE);
}
} }
kmem_cache_free(rsxx_dma_pool, dma); kmem_cache_free(rsxx_dma_pool, dma);
...@@ -1057,11 +1059,14 @@ int rsxx_eeh_save_issued_dmas(struct rsxx_cardinfo *card) ...@@ -1057,11 +1059,14 @@ int rsxx_eeh_save_issued_dmas(struct rsxx_cardinfo *card)
else else
card->ctrl[i].stats.reads_issued--; card->ctrl[i].stats.reads_issued--;
pci_unmap_page(card->dev, dma->dma_addr, if (dma->cmd != HW_CMD_BLK_DISCARD) {
get_dma_size(dma), pci_unmap_page(card->dev, dma->dma_addr,
dma->cmd == HW_CMD_BLK_WRITE ? get_dma_size(dma),
PCI_DMA_TODEVICE : dma->cmd == HW_CMD_BLK_WRITE ?
PCI_DMA_FROMDEVICE); PCI_DMA_TODEVICE :
PCI_DMA_FROMDEVICE);
}
list_add_tail(&dma->list, &issued_dmas[i]); list_add_tail(&dma->list, &issued_dmas[i]);
push_tracker(card->ctrl[i].trackers, j); push_tracker(card->ctrl[i].trackers, j);
cnt++; cnt++;
......
...@@ -52,7 +52,7 @@ struct proc_cmd; ...@@ -52,7 +52,7 @@ struct proc_cmd;
#define RS70_PCI_REV_SUPPORTED 4 #define RS70_PCI_REV_SUPPORTED 4
#define DRIVER_NAME "rsxx" #define DRIVER_NAME "rsxx"
#define DRIVER_VERSION "4.0.1.2498" #define DRIVER_VERSION "4.0.2.2510"
/* Block size is 4096 */ /* Block size is 4096 */
#define RSXX_HW_BLK_SHIFT 12 #define RSXX_HW_BLK_SHIFT 12
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册