aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeith Busch <keith.busch@intel.com>2015-09-03 10:18:17 -0400
committerJens Axboe <axboe@fb.com>2015-09-23 16:45:57 -0400
commitbda4e0fb3126aca15586d165b5a15a37edc0a984 (patch)
tree0fbe3bc3f63b56b0d491ca8f870b4672a2546f20
parentadbe734b2ae5517b8659997909677687b963d73c (diff)
NVMe: Set affinity after allocating request queues
The asynchronous namespace scanning caused affinity hints to be set before its tagset initialized, so there was no cpu mask to set the hint. This patch moves the affinity hint setting to after namespaces are scanned. Reported-by: 김경산 <ks0204.kim@samsung.com> Signed-off-by: Keith Busch <keith.busch@intel.com> Signed-off-by: Jens Axboe <axboe@fb.com>
-rw-r--r--drivers/block/nvme-core.c36
1 files changed, 17 insertions, 19 deletions
diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c
index b97fc3fe0916..30758bdf69ea 100644
--- a/drivers/block/nvme-core.c
+++ b/drivers/block/nvme-core.c
@@ -2439,6 +2439,22 @@ static void nvme_scan_namespaces(struct nvme_dev *dev, unsigned nn)
2439 list_sort(NULL, &dev->namespaces, ns_cmp); 2439 list_sort(NULL, &dev->namespaces, ns_cmp);
2440} 2440}
2441 2441
2442static void nvme_set_irq_hints(struct nvme_dev *dev)
2443{
2444 struct nvme_queue *nvmeq;
2445 int i;
2446
2447 for (i = 0; i < dev->online_queues; i++) {
2448 nvmeq = dev->queues[i];
2449
2450 if (!nvmeq->tags || !(*nvmeq->tags))
2451 continue;
2452
2453 irq_set_affinity_hint(dev->entry[nvmeq->cq_vector].vector,
2454 blk_mq_tags_cpumask(*nvmeq->tags));
2455 }
2456}
2457
2442static void nvme_dev_scan(struct work_struct *work) 2458static void nvme_dev_scan(struct work_struct *work)
2443{ 2459{
2444 struct nvme_dev *dev = container_of(work, struct nvme_dev, scan_work); 2460 struct nvme_dev *dev = container_of(work, struct nvme_dev, scan_work);
@@ -2450,6 +2466,7 @@ static void nvme_dev_scan(struct work_struct *work)
2450 return; 2466 return;
2451 nvme_scan_namespaces(dev, le32_to_cpup(&ctrl->nn)); 2467 nvme_scan_namespaces(dev, le32_to_cpup(&ctrl->nn));
2452 kfree(ctrl); 2468 kfree(ctrl);
2469 nvme_set_irq_hints(dev);
2453} 2470}
2454 2471
2455/* 2472/*
@@ -2953,22 +2970,6 @@ static const struct file_operations nvme_dev_fops = {
2953 .compat_ioctl = nvme_dev_ioctl, 2970 .compat_ioctl = nvme_dev_ioctl,
2954}; 2971};
2955 2972
2956static void nvme_set_irq_hints(struct nvme_dev *dev)
2957{
2958 struct nvme_queue *nvmeq;
2959 int i;
2960
2961 for (i = 0; i < dev->online_queues; i++) {
2962 nvmeq = dev->queues[i];
2963
2964 if (!nvmeq->tags || !(*nvmeq->tags))
2965 continue;
2966
2967 irq_set_affinity_hint(dev->entry[nvmeq->cq_vector].vector,
2968 blk_mq_tags_cpumask(*nvmeq->tags));
2969 }
2970}
2971
2972static int nvme_dev_start(struct nvme_dev *dev) 2973static int nvme_dev_start(struct nvme_dev *dev)
2973{ 2974{
2974 int result; 2975 int result;
@@ -3010,8 +3011,6 @@ static int nvme_dev_start(struct nvme_dev *dev)
3010 if (result) 3011 if (result)
3011 goto free_tags; 3012 goto free_tags;
3012 3013
3013 nvme_set_irq_hints(dev);
3014
3015 dev->event_limit = 1; 3014 dev->event_limit = 1;
3016 return result; 3015 return result;
3017 3016
@@ -3062,7 +3061,6 @@ static int nvme_dev_resume(struct nvme_dev *dev)
3062 } else { 3061 } else {
3063 nvme_unfreeze_queues(dev); 3062 nvme_unfreeze_queues(dev);
3064 nvme_dev_add(dev); 3063 nvme_dev_add(dev);
3065 nvme_set_irq_hints(dev);
3066 } 3064 }
3067 return 0; 3065 return 0;
3068} 3066}