diff options
Diffstat (limited to 'drivers/nvme/host/pci.c')
| -rw-r--r-- | drivers/nvme/host/pci.c | 59 | 
1 files changed, 35 insertions, 24 deletions
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index 6fe7af00a1f4..b6f43b738f03 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -1141,7 +1141,7 @@ static bool nvme_should_reset(struct nvme_dev *dev, u32 csts)  	/* If there is a reset/reinit ongoing, we shouldn't reset again. */  	switch (dev->ctrl.state) {  	case NVME_CTRL_RESETTING: -	case NVME_CTRL_RECONNECTING: +	case NVME_CTRL_CONNECTING:  		return false;  	default:  		break; @@ -1153,12 +1153,6 @@ static bool nvme_should_reset(struct nvme_dev *dev, u32 csts)  	if (!(csts & NVME_CSTS_CFS) && !nssro)  		return false; -	/* If PCI error recovery process is happening, we cannot reset or -	 * the recovery mechanism will surely fail. -	 */ -	if (pci_channel_offline(to_pci_dev(dev->dev))) -		return false; -  	return true;  } @@ -1189,6 +1183,13 @@ static enum blk_eh_timer_return nvme_timeout(struct request *req, bool reserved)  	struct nvme_command cmd;  	u32 csts = readl(dev->bar + NVME_REG_CSTS); +	/* If PCI error recovery process is happening, we cannot reset or +	 * the recovery mechanism will surely fail. +	 */ +	mb(); +	if (pci_channel_offline(to_pci_dev(dev->dev))) +		return BLK_EH_RESET_TIMER; +  	/*  	 * Reset immediately if the controller is failed  	 */ @@ -1215,13 +1216,17 @@ static enum blk_eh_timer_return nvme_timeout(struct request *req, bool reserved)  	 * cancellation error. All outstanding requests are completed on  	 * shutdown, so we return BLK_EH_HANDLED.  	 */ -	if (dev->ctrl.state == NVME_CTRL_RESETTING) { +	switch (dev->ctrl.state) { +	case NVME_CTRL_CONNECTING: +	case NVME_CTRL_RESETTING:  		dev_warn(dev->ctrl.device,  			 "I/O %d QID %d timeout, disable controller\n",  			 req->tag, nvmeq->qid);  		nvme_dev_disable(dev, false);  		nvme_req(req)->flags |= NVME_REQ_CANCELLED;  		return BLK_EH_HANDLED; +	default: +		break;  	}  	/* @@ -1364,18 +1369,14 @@ static int nvme_cmb_qdepth(struct nvme_dev *dev, int nr_io_queues,  static int nvme_alloc_sq_cmds(struct nvme_dev *dev, struct nvme_queue *nvmeq,  				int qid, int depth)  { -	if (qid && dev->cmb && use_cmb_sqes && (dev->cmbsz & NVME_CMBSZ_SQS)) { -		unsigned offset = (qid - 1) * roundup(SQ_SIZE(depth), -						      dev->ctrl.page_size); -		nvmeq->sq_dma_addr = dev->cmb_bus_addr + offset; -		nvmeq->sq_cmds_io = dev->cmb + offset; -	} else { -		nvmeq->sq_cmds = dma_alloc_coherent(dev->dev, SQ_SIZE(depth), -					&nvmeq->sq_dma_addr, GFP_KERNEL); -		if (!nvmeq->sq_cmds) -			return -ENOMEM; -	} +	/* CMB SQEs will be mapped before creation */ +	if (qid && dev->cmb && use_cmb_sqes && (dev->cmbsz & NVME_CMBSZ_SQS)) +		return 0; +	nvmeq->sq_cmds = dma_alloc_coherent(dev->dev, SQ_SIZE(depth), +					    &nvmeq->sq_dma_addr, GFP_KERNEL); +	if (!nvmeq->sq_cmds) +		return -ENOMEM;  	return 0;  } @@ -1449,10 +1450,17 @@ static int nvme_create_queue(struct nvme_queue *nvmeq, int qid)  	struct nvme_dev *dev = nvmeq->dev;  	int result; +	if (dev->cmb && use_cmb_sqes && (dev->cmbsz & NVME_CMBSZ_SQS)) { +		unsigned offset = (qid - 1) * roundup(SQ_SIZE(nvmeq->q_depth), +						      dev->ctrl.page_size); +		nvmeq->sq_dma_addr = dev->cmb_bus_addr + offset; +		nvmeq->sq_cmds_io = dev->cmb + offset; +	} +  	nvmeq->cq_vector = qid - 1;  	result = adapter_alloc_cq(dev, qid, nvmeq);  	if (result < 0) -		return result; +		goto release_vector;  	result = adapter_alloc_sq(dev, qid, nvmeq);  	if (result < 0) @@ -1466,9 +1474,12 @@ static int nvme_create_queue(struct nvme_queue *nvmeq, int qid)  	return result;   release_sq: +	dev->online_queues--;  	adapter_delete_sq(dev, qid);   release_cq:  	adapter_delete_cq(dev, qid); + release_vector: +	nvmeq->cq_vector = -1;  	return result;  } @@ -1903,7 +1914,7 @@ static int nvme_setup_io_queues(struct nvme_dev *dev)  	int result, nr_io_queues;  	unsigned long size; -	nr_io_queues = num_present_cpus(); +	nr_io_queues = num_possible_cpus();  	result = nvme_set_queue_count(&dev->ctrl, &nr_io_queues);  	if (result < 0)  		return result; @@ -2288,12 +2299,12 @@ static void nvme_reset_work(struct work_struct *work)  		nvme_dev_disable(dev, false);  	/* -	 * Introduce RECONNECTING state from nvme-fc/rdma transports to mark the +	 * Introduce CONNECTING state from nvme-fc/rdma transports to mark the  	 * initializing procedure here.  	 */ -	if (!nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_RECONNECTING)) { +	if (!nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_CONNECTING)) {  		dev_warn(dev->ctrl.device, -			"failed to mark controller RECONNECTING\n"); +			"failed to mark controller CONNECTING\n");  		goto out;  	}  | 

