aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMing Lei <ming.lei@redhat.com>2017-04-27 09:45:18 -0400
committerJens Axboe <axboe@fb.com>2017-04-27 09:45:18 -0400
commita4e84aae8139aca9fbfbced1f45c51ca81b57488 (patch)
tree21b67ddec9938be7ea6222a301074f0274c42780
parent0eebd005dd07c162e6af053be0ab440dd766b1d5 (diff)
mtip32xx: use runtime tag to initialize command header
mtip32xx supposes that 'request_idx' passed to .init_request() is tag of the request, and use that as request's tag to initialize command header. After MQ IO scheduler is in, request tag assigned isn't same with the request index anymore, so cause strange hardware failure on mtip32xx, even whole system panic is triggered. This patch fixes the issue by initializing command header via request's real tag. Signed-off-by: Ming Lei <ming.lei@redhat.com> Signed-off-by: Jens Axboe <axboe@fb.com>
-rw-r--r--drivers/block/mtip32xx/mtip32xx.c36
1 files changed, 24 insertions, 12 deletions
diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c
index 54c8736038de..fa3dd4a55371 100644
--- a/drivers/block/mtip32xx/mtip32xx.c
+++ b/drivers/block/mtip32xx/mtip32xx.c
@@ -169,6 +169,25 @@ static bool mtip_check_surprise_removal(struct pci_dev *pdev)
169 return false; /* device present */ 169 return false; /* device present */
170} 170}
171 171
172/* we have to use runtime tag to setup command header */
173static void mtip_init_cmd_header(struct request *rq)
174{
175 struct driver_data *dd = rq->q->queuedata;
176 struct mtip_cmd *cmd = blk_mq_rq_to_pdu(rq);
177 u32 host_cap_64 = readl(dd->mmio + HOST_CAP) & HOST_CAP_64;
178
179 /* Point the command headers at the command tables. */
180 cmd->command_header = dd->port->command_list +
181 (sizeof(struct mtip_cmd_hdr) * rq->tag);
182 cmd->command_header_dma = dd->port->command_list_dma +
183 (sizeof(struct mtip_cmd_hdr) * rq->tag);
184
185 if (host_cap_64)
186 cmd->command_header->ctbau = __force_bit2int cpu_to_le32((cmd->command_dma >> 16) >> 16);
187
188 cmd->command_header->ctba = __force_bit2int cpu_to_le32(cmd->command_dma & 0xFFFFFFFF);
189}
190
172static struct mtip_cmd *mtip_get_int_command(struct driver_data *dd) 191static struct mtip_cmd *mtip_get_int_command(struct driver_data *dd)
173{ 192{
174 struct request *rq; 193 struct request *rq;
@@ -180,6 +199,9 @@ static struct mtip_cmd *mtip_get_int_command(struct driver_data *dd)
180 if (IS_ERR(rq)) 199 if (IS_ERR(rq))
181 return NULL; 200 return NULL;
182 201
202 /* Internal cmd isn't submitted via .queue_rq */
203 mtip_init_cmd_header(rq);
204
183 return blk_mq_rq_to_pdu(rq); 205 return blk_mq_rq_to_pdu(rq);
184} 206}
185 207
@@ -3809,6 +3831,8 @@ static int mtip_queue_rq(struct blk_mq_hw_ctx *hctx,
3809 struct request *rq = bd->rq; 3831 struct request *rq = bd->rq;
3810 int ret; 3832 int ret;
3811 3833
3834 mtip_init_cmd_header(rq);
3835
3812 if (unlikely(mtip_check_unal_depth(hctx, rq))) 3836 if (unlikely(mtip_check_unal_depth(hctx, rq)))
3813 return BLK_MQ_RQ_QUEUE_BUSY; 3837 return BLK_MQ_RQ_QUEUE_BUSY;
3814 3838
@@ -3839,7 +3863,6 @@ static int mtip_init_cmd(void *data, struct request *rq, unsigned int hctx_idx,
3839{ 3863{
3840 struct driver_data *dd = data; 3864 struct driver_data *dd = data;
3841 struct mtip_cmd *cmd = blk_mq_rq_to_pdu(rq); 3865 struct mtip_cmd *cmd = blk_mq_rq_to_pdu(rq);
3842 u32 host_cap_64 = readl(dd->mmio + HOST_CAP) & HOST_CAP_64;
3843 3866
3844 /* 3867 /*
3845 * For flush requests, request_idx starts at the end of the 3868 * For flush requests, request_idx starts at the end of the
@@ -3856,17 +3879,6 @@ static int mtip_init_cmd(void *data, struct request *rq, unsigned int hctx_idx,
3856 3879
3857 memset(cmd->command, 0, CMD_DMA_ALLOC_SZ); 3880 memset(cmd->command, 0, CMD_DMA_ALLOC_SZ);
3858 3881
3859 /* Point the command headers at the command tables. */
3860 cmd->command_header = dd->port->command_list +
3861 (sizeof(struct mtip_cmd_hdr) * request_idx);
3862 cmd->command_header_dma = dd->port->command_list_dma +
3863 (sizeof(struct mtip_cmd_hdr) * request_idx);
3864
3865 if (host_cap_64)
3866 cmd->command_header->ctbau = __force_bit2int cpu_to_le32((cmd->command_dma >> 16) >> 16);
3867
3868 cmd->command_header->ctba = __force_bit2int cpu_to_le32(cmd->command_dma & 0xFFFFFFFF);
3869
3870 sg_init_table(cmd->sg, MTIP_MAX_SG); 3882 sg_init_table(cmd->sg, MTIP_MAX_SG);
3871 return 0; 3883 return 0;
3872} 3884}