aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeith Busch <keith.busch@intel.com>2015-06-01 16:28:14 -0400
committerJens Axboe <axboe@fb.com>2015-06-05 12:58:34 -0400
commita5768aa887fb636f0cc4c83a2f1242506aaf50f6 (patch)
tree872ae3d7e554faa24994d62ac7ff921aa47a9aed
parentb281ebb817b009dc586347d7800b80944ba3ec18 (diff)
NVMe: Automatic namespace rescan
Namespaces may be dynamically allocated and deleted or attached and detached. This has the driver rescan the device for namespace changes after each device reset or namespace change asynchronous event. There could potentially be many detached namespaces that we don't want polluting /dev/ with unusable block handles, so this will delete disks if the namespace is not active as indicated by the response from identify namespace. This also skips adding the disk if no capacity is provisioned to the namespace in the first place. Signed-off-by: Keith Busch <keith.busch@intel.com> Signed-off-by: Jens Axboe <axboe@fb.com>
-rw-r--r--drivers/block/nvme-core.c159
-rw-r--r--include/linux/nvme.h1
-rw-r--r--include/uapi/linux/nvme.h4
3 files changed, 132 insertions, 32 deletions
diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c
index cae7cac6cc43..2072ae81c13a 100644
--- a/drivers/block/nvme-core.c
+++ b/drivers/block/nvme-core.c
@@ -29,6 +29,7 @@
29#include <linux/kdev_t.h> 29#include <linux/kdev_t.h>
30#include <linux/kthread.h> 30#include <linux/kthread.h>
31#include <linux/kernel.h> 31#include <linux/kernel.h>
32#include <linux/list_sort.h>
32#include <linux/mm.h> 33#include <linux/mm.h>
33#include <linux/module.h> 34#include <linux/module.h>
34#include <linux/moduleparam.h> 35#include <linux/moduleparam.h>
@@ -300,9 +301,16 @@ static void async_req_completion(struct nvme_queue *nvmeq, void *ctx,
300 301
301 if (status == NVME_SC_SUCCESS || status == NVME_SC_ABORT_REQ) 302 if (status == NVME_SC_SUCCESS || status == NVME_SC_ABORT_REQ)
302 ++nvmeq->dev->event_limit; 303 ++nvmeq->dev->event_limit;
303 if (status == NVME_SC_SUCCESS) 304 if (status != NVME_SC_SUCCESS)
304 dev_warn(nvmeq->q_dmadev, 305 return;
305 "async event result %08x\n", result); 306
307 switch (result & 0xff07) {
308 case NVME_AER_NOTICE_NS_CHANGED:
309 dev_info(nvmeq->q_dmadev, "rescanning\n");
310 schedule_work(&nvmeq->dev->scan_work);
311 default:
312 dev_warn(nvmeq->q_dmadev, "async event result %08x\n", result);
313 }
306} 314}
307 315
308static void abort_completion(struct nvme_queue *nvmeq, void *ctx, 316static void abort_completion(struct nvme_queue *nvmeq, void *ctx,
@@ -1923,8 +1931,13 @@ static int nvme_revalidate_disk(struct gendisk *disk)
1923 unsigned short bs; 1931 unsigned short bs;
1924 1932
1925 if (nvme_identify_ns(dev, ns->ns_id, &id)) { 1933 if (nvme_identify_ns(dev, ns->ns_id, &id)) {
1926 dev_warn(dev->dev, "%s: Identify failure\n", __func__); 1934 dev_warn(dev->dev, "%s: Identify failure nvme%dn%d\n", __func__,
1927 return 0; 1935 dev->instance, ns->ns_id);
1936 return -ENODEV;
1937 }
1938 if (id->ncap == 0) {
1939 kfree(id);
1940 return -ENODEV;
1928 } 1941 }
1929 1942
1930 old_ms = ns->ms; 1943 old_ms = ns->ms;
@@ -1958,7 +1971,7 @@ static int nvme_revalidate_disk(struct gendisk *disk)
1958 !ns->ext) 1971 !ns->ext)
1959 nvme_init_integrity(ns); 1972 nvme_init_integrity(ns);
1960 1973
1961 if (id->ncap == 0 || (ns->ms && !blk_get_integrity(disk))) 1974 if (ns->ms && !blk_get_integrity(disk))
1962 set_capacity(disk, 0); 1975 set_capacity(disk, 0);
1963 else 1976 else
1964 set_capacity(disk, le64_to_cpup(&id->nsze) << (ns->lba_shift - 9)); 1977 set_capacity(disk, le64_to_cpup(&id->nsze) << (ns->lba_shift - 9));
@@ -2073,11 +2086,16 @@ static void nvme_alloc_ns(struct nvme_dev *dev, unsigned nsid)
2073 * requires it. 2086 * requires it.
2074 */ 2087 */
2075 set_capacity(disk, 0); 2088 set_capacity(disk, 0);
2076 nvme_revalidate_disk(ns->disk); 2089 if (nvme_revalidate_disk(ns->disk))
2090 goto out_free_disk;
2091
2077 add_disk(ns->disk); 2092 add_disk(ns->disk);
2078 if (ns->ms) 2093 if (ns->ms)
2079 revalidate_disk(ns->disk); 2094 revalidate_disk(ns->disk);
2080 return; 2095 return;
2096 out_free_disk:
2097 kfree(disk);
2098 list_del(&ns->list);
2081 out_free_queue: 2099 out_free_queue:
2082 blk_cleanup_queue(ns->queue); 2100 blk_cleanup_queue(ns->queue);
2083 out_free_ns: 2101 out_free_ns:
@@ -2194,6 +2212,99 @@ static int nvme_setup_io_queues(struct nvme_dev *dev)
2194 return result; 2212 return result;
2195} 2213}
2196 2214
2215static void nvme_free_namespace(struct nvme_ns *ns)
2216{
2217 list_del(&ns->list);
2218
2219 spin_lock(&dev_list_lock);
2220 ns->disk->private_data = NULL;
2221 spin_unlock(&dev_list_lock);
2222
2223 put_disk(ns->disk);
2224 kfree(ns);
2225}
2226
2227static int ns_cmp(void *priv, struct list_head *a, struct list_head *b)
2228{
2229 struct nvme_ns *nsa = container_of(a, struct nvme_ns, list);
2230 struct nvme_ns *nsb = container_of(b, struct nvme_ns, list);
2231
2232 return nsa->ns_id - nsb->ns_id;
2233}
2234
2235static struct nvme_ns *nvme_find_ns(struct nvme_dev *dev, unsigned nsid)
2236{
2237 struct nvme_ns *ns;
2238
2239 list_for_each_entry(ns, &dev->namespaces, list) {
2240 if (ns->ns_id == nsid)
2241 return ns;
2242 if (ns->ns_id > nsid)
2243 break;
2244 }
2245 return NULL;
2246}
2247
2248static inline bool nvme_io_incapable(struct nvme_dev *dev)
2249{
2250 return (!dev->bar || readl(&dev->bar->csts) & NVME_CSTS_CFS ||
2251 dev->online_queues < 2);
2252}
2253
2254static void nvme_ns_remove(struct nvme_ns *ns)
2255{
2256 bool kill = nvme_io_incapable(ns->dev) && !blk_queue_dying(ns->queue);
2257
2258 if (kill)
2259 blk_set_queue_dying(ns->queue);
2260 if (ns->disk->flags & GENHD_FL_UP) {
2261 if (blk_get_integrity(ns->disk))
2262 blk_integrity_unregister(ns->disk);
2263 del_gendisk(ns->disk);
2264 }
2265 if (kill || !blk_queue_dying(ns->queue)) {
2266 blk_mq_abort_requeue_list(ns->queue);
2267 blk_cleanup_queue(ns->queue);
2268 }
2269}
2270
2271static void nvme_scan_namespaces(struct nvme_dev *dev, unsigned nn)
2272{
2273 struct nvme_ns *ns, *next;
2274 unsigned i;
2275
2276 for (i = 1; i <= nn; i++) {
2277 ns = nvme_find_ns(dev, i);
2278 if (ns) {
2279 if (revalidate_disk(ns->disk)) {
2280 nvme_ns_remove(ns);
2281 nvme_free_namespace(ns);
2282 }
2283 } else
2284 nvme_alloc_ns(dev, i);
2285 }
2286 list_for_each_entry_safe(ns, next, &dev->namespaces, list) {
2287 if (ns->ns_id > nn) {
2288 nvme_ns_remove(ns);
2289 nvme_free_namespace(ns);
2290 }
2291 }
2292 list_sort(NULL, &dev->namespaces, ns_cmp);
2293}
2294
2295static void nvme_dev_scan(struct work_struct *work)
2296{
2297 struct nvme_dev *dev = container_of(work, struct nvme_dev, scan_work);
2298 struct nvme_id_ctrl *ctrl;
2299
2300 if (!dev->tagset.tags)
2301 return;
2302 if (nvme_identify_ctrl(dev, &ctrl))
2303 return;
2304 nvme_scan_namespaces(dev, le32_to_cpup(&ctrl->nn));
2305 kfree(ctrl);
2306}
2307
2197/* 2308/*
2198 * Return: error value if an error occurred setting up the queues or calling 2309 * Return: error value if an error occurred setting up the queues or calling
2199 * Identify Device. 0 if these succeeded, even if adding some of the 2310 * Identify Device. 0 if these succeeded, even if adding some of the
@@ -2204,7 +2315,7 @@ static int nvme_dev_add(struct nvme_dev *dev)
2204{ 2315{
2205 struct pci_dev *pdev = to_pci_dev(dev->dev); 2316 struct pci_dev *pdev = to_pci_dev(dev->dev);
2206 int res; 2317 int res;
2207 unsigned nn, i; 2318 unsigned nn;
2208 struct nvme_id_ctrl *ctrl; 2319 struct nvme_id_ctrl *ctrl;
2209 int shift = NVME_CAP_MPSMIN(readq(&dev->bar->cap)) + 12; 2320 int shift = NVME_CAP_MPSMIN(readq(&dev->bar->cap)) + 12;
2210 2321
@@ -2250,9 +2361,7 @@ static int nvme_dev_add(struct nvme_dev *dev)
2250 if (blk_mq_alloc_tag_set(&dev->tagset)) 2361 if (blk_mq_alloc_tag_set(&dev->tagset))
2251 return 0; 2362 return 0;
2252 2363
2253 for (i = 1; i <= nn; i++) 2364 schedule_work(&dev->scan_work);