* [PATCH 0/2] NVMe: Controller resets
@ 2013-08-07 20:44 Keith Busch
2013-08-07 20:44 ` [PATCH 1/2] NVMe: Reset failed controller Keith Busch
2013-08-07 20:44 ` [PATCH 2/2] NVMe: User initiated controller reset Keith Busch
0 siblings, 2 replies; 3+ messages in thread
From: Keith Busch @ 2013-08-07 20:44 UTC (permalink / raw)
Some controller reset action. These depend on this patch set here:
http://merlin.infradead.org/pipermail/linux-nvme/2013-July/000331.html
Keith Busch (2):
NVMe: Reset failed controller
NVMe: User initiated controller reset
drivers/block/nvme-core.c | 43 ++++++++++++++++++++++++++++++++++++++++++-
include/linux/nvme.h | 1 +
2 files changed, 43 insertions(+), 1 deletion(-)
--
1.7.10.4
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH 1/2] NVMe: Reset failed controller
2013-08-07 20:44 [PATCH 0/2] NVMe: Controller resets Keith Busch
@ 2013-08-07 20:44 ` Keith Busch
2013-08-07 20:44 ` [PATCH 2/2] NVMe: User initiated controller reset Keith Busch
1 sibling, 0 replies; 3+ messages in thread
From: Keith Busch @ 2013-08-07 20:44 UTC (permalink / raw)
Polls on the controller fatal status bit and resets the controller per
the nvme spec on this condition.
Signed-off-by: Keith Busch <keith.busch at intel.com>
---
drivers/block/nvme-core.c | 30 +++++++++++++++++++++++++++++-
include/linux/nvme.h | 1 +
2 files changed, 30 insertions(+), 1 deletion(-)
diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c
index 52cf479..f401e2b 100644
--- a/drivers/block/nvme-core.c
+++ b/drivers/block/nvme-core.c
@@ -58,6 +58,7 @@ module_param(use_threaded_interrupts, int, 0);
static DEFINE_SPINLOCK(dev_list_lock);
static LIST_HEAD(dev_list);
static struct task_struct *nvme_thread;
+static struct workqueue_struct *nvme_workq;
/*
* An NVM Express queue. Each device has at least two (one for admin
@@ -1605,6 +1606,12 @@ static int nvme_kthread(void *data)
spin_lock(&dev_list_lock);
list_for_each_entry(dev, &dev_list, node) {
int i;
+ if (readl(&dev->bar->csts) & NVME_CSTS_CFS) {
+ dev_warn(&dev->pci_dev->dev,
+ "failed status, reset controller\n");
+ queue_work(nvme_workq, &dev->ws);
+ continue;
+ }
for (i = 0; i < dev->queue_count; i++) {
struct nvme_queue *nvmeq = dev->queues[i];
if (!nvmeq)
@@ -2151,6 +2158,19 @@ static int nvme_dev_start(struct nvme_dev *dev)
return result;
}
+static void nvme_dev_reset(struct nvme_dev *dev)
+{
+ nvme_dev_shutdown(dev);
+ if (nvme_dev_start(dev))
+ nvme_free_queues(dev);
+}
+
+static void nvme_reset_failed_dev(struct work_struct *ws)
+{
+ struct nvme_dev *dev = container_of(ws, struct nvme_dev, ws);
+ nvme_dev_reset(dev);
+}
+
static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
int result = -ENOMEM;
@@ -2178,6 +2198,7 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (result)
goto release;
+ INIT_WORK(&dev->ws, nvme_reset_failed_dev);
result = nvme_dev_start(dev);
if (result)
goto release_pools;
@@ -2288,9 +2309,14 @@ static int __init nvme_init(void)
if (IS_ERR(nvme_thread))
return PTR_ERR(nvme_thread);
+ result = -ENOMEM;
+ nvme_workq = create_workqueue("nvme");
+ if (!nvme_workq)
+ goto kill_kthread;
+
result = register_blkdev(nvme_major, "nvme");
if (result < 0)
- goto kill_thread;
+ goto kill_workq;
else if (result > 0)
nvme_major = result;
@@ -2301,6 +2327,8 @@ static int __init nvme_init(void)
unregister_blkdev:
unregister_blkdev(nvme_major, "nvme");
+ kill_workq:
+ destroy_workqueue(nvme_workq);
kill_kthread:
kthread_stop(nvme_thread);
return result;
diff --git a/include/linux/nvme.h b/include/linux/nvme.h
index 26ebcf4..612e640 100644
--- a/include/linux/nvme.h
+++ b/include/linux/nvme.h
@@ -87,6 +87,7 @@ struct nvme_dev {
struct list_head namespaces;
struct kref kref;
struct miscdevice miscdev;
+ struct work_struct ws;
char name[12];
char serial[20];
char model[40];
--
1.7.10.4
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH 2/2] NVMe: User initiated controller reset
2013-08-07 20:44 [PATCH 0/2] NVMe: Controller resets Keith Busch
2013-08-07 20:44 ` [PATCH 1/2] NVMe: Reset failed controller Keith Busch
@ 2013-08-07 20:44 ` Keith Busch
1 sibling, 0 replies; 3+ messages in thread
From: Keith Busch @ 2013-08-07 20:44 UTC (permalink / raw)
Creates a sysfs entry for each nvme controller that when written to
initiates a controller reset. This may be done by a user if they need
to reset the controller for any reason. For example, it may be required
as part of an firmware activate procedure.
Signed-off-by: Keith Busch <keith.busch at intel.com>
---
drivers/block/nvme-core.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c
index f401e2b..ee29e2e 100644
--- a/drivers/block/nvme-core.c
+++ b/drivers/block/nvme-core.c
@@ -2171,6 +2171,17 @@ static void nvme_reset_failed_dev(struct work_struct *ws)
nvme_dev_reset(dev);
}
+static ssize_t nvme_reset(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct pci_dev *pdev = container_of(dev, struct pci_dev, dev);
+ struct nvme_dev *ndev = pci_get_drvdata(pdev);
+
+ nvme_dev_reset(ndev);
+ return count;
+}
+static DEVICE_ATTR(reset_controller, S_IWUSR, NULL, nvme_reset);
+
static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
int result = -ENOMEM;
@@ -2217,6 +2228,7 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)
goto remove;
kref_init(&dev->kref);
+ device_create_file(&pdev->dev, &dev_attr_reset_controller);
return 0;
remove:
@@ -2238,6 +2250,7 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)
static void nvme_remove(struct pci_dev *pdev)
{
struct nvme_dev *dev = pci_get_drvdata(pdev);
+ device_remove_file(&pdev->dev, &dev_attr_reset_controller);
misc_deregister(&dev->miscdev);
kref_put(&dev->kref, nvme_free_dev);
}
--
1.7.10.4
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2013-08-07 20:44 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-08-07 20:44 [PATCH 0/2] NVMe: Controller resets Keith Busch
2013-08-07 20:44 ` [PATCH 1/2] NVMe: Reset failed controller Keith Busch
2013-08-07 20:44 ` [PATCH 2/2] NVMe: User initiated controller reset Keith Busch
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).