All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] NVMe: User initiated rescan
@ 2016-05-10 22:23 Keith Busch
  2016-05-11  9:40 ` Johannes Thumshirn
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Keith Busch @ 2016-05-10 22:23 UTC (permalink / raw)


This provides user ioctl and sysfs methods that can be used to request
the driver rescan a controller and its namespaces. This is less harsh
than doing a controller reset, which temporarily halts all IO just to
surface a newly attached namespace.

This is mainly useful for controllers that implement namespace management,
but do not support the namespace notify change asynchronous event
notification.

Signed-off-by: Keith Busch <keith.busch at intel.com>
---
 drivers/nvme/host/core.c        | 22 ++++++++++++++++++++--
 drivers/nvme/host/nvme.h        |  2 +-
 include/uapi/linux/nvme_ioctl.h |  1 +
 3 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 2df0351d..b85c4b1 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -1216,6 +1216,8 @@ static long nvme_dev_ioctl(struct file *file, unsigned int cmd,
 		return ctrl->ops->reset_ctrl(ctrl);
 	case NVME_IOCTL_SUBSYS_RESET:
 		return nvme_reset_subsystem(ctrl);
+	case NVME_IOCTL_RESCAN:
+		return nvme_queue_scan(ctrl);
 	default:
 		return -ENOTTY;
 	}
@@ -1243,6 +1245,20 @@ static ssize_t nvme_sysfs_reset(struct device *dev,
 }
 static DEVICE_ATTR(reset_controller, S_IWUSR, NULL, nvme_sysfs_reset);
 
+static ssize_t nvme_sysfs_rescan(struct device *dev,
+				struct device_attribute *attr, const char *buf,
+				size_t count)
+{
+	struct nvme_ctrl *ctrl = dev_get_drvdata(dev);
+	int ret;
+
+	ret = nvme_queue_scan(ctrl);
+	if (ret < 0)
+		return ret;
+	return count;
+}
+static DEVICE_ATTR(rescan_controller, S_IWUSR, NULL, nvme_sysfs_rescan);
+
 static ssize_t wwid_show(struct device *dev, struct device_attribute *attr,
 								char *buf)
 {
@@ -1346,6 +1362,7 @@ nvme_show_int_function(cntlid);
 
 static struct attribute *nvme_dev_attrs[] = {
 	&dev_attr_reset_controller.attr,
+	&dev_attr_rescan_controller.attr,
 	&dev_attr_model.attr,
 	&dev_attr_serial.attr,
 	&dev_attr_firmware_rev.attr,
@@ -1569,14 +1586,15 @@ static void nvme_scan_work(struct work_struct *work)
 		ctrl->ops->post_scan(ctrl);
 }
 
-void nvme_queue_scan(struct nvme_ctrl *ctrl)
+int nvme_queue_scan(struct nvme_ctrl *ctrl)
 {
 	/*
 	 * Do not queue new scan work when a controller is reset during
 	 * removal.
 	 */
 	if (ctrl->state == NVME_CTRL_LIVE)
-		schedule_work(&ctrl->scan_work);
+		return schedule_work(&ctrl->scan_work);
+	return -EBUSY;
 }
 EXPORT_SYMBOL_GPL(nvme_queue_scan);
 
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index 114b928..997b9ec 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -217,7 +217,7 @@ void nvme_uninit_ctrl(struct nvme_ctrl *ctrl);
 void nvme_put_ctrl(struct nvme_ctrl *ctrl);
 int nvme_init_identify(struct nvme_ctrl *ctrl);
 
-void nvme_queue_scan(struct nvme_ctrl *ctrl);
+int nvme_queue_scan(struct nvme_ctrl *ctrl);
 void nvme_remove_namespaces(struct nvme_ctrl *ctrl);
 
 #define NVME_NR_AERS	1
diff --git a/include/uapi/linux/nvme_ioctl.h b/include/uapi/linux/nvme_ioctl.h
index c4b2a3f..50ff21f 100644
--- a/include/uapi/linux/nvme_ioctl.h
+++ b/include/uapi/linux/nvme_ioctl.h
@@ -61,5 +61,6 @@ struct nvme_passthru_cmd {
 #define NVME_IOCTL_IO_CMD	_IOWR('N', 0x43, struct nvme_passthru_cmd)
 #define NVME_IOCTL_RESET	_IO('N', 0x44)
 #define NVME_IOCTL_SUBSYS_RESET	_IO('N', 0x45)
+#define NVME_IOCTL_RESCAN	_IO('N', 0x46)
 
 #endif /* _UAPI_LINUX_NVME_IOCTL_H */
-- 
2.7.2

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH] NVMe: User initiated rescan
  2016-05-10 22:23 [PATCH] NVMe: User initiated rescan Keith Busch
@ 2016-05-11  9:40 ` Johannes Thumshirn
  2016-05-11 19:00 ` Brandon Schulz
  2016-05-12  7:00 ` Christoph Hellwig
  2 siblings, 0 replies; 4+ messages in thread
From: Johannes Thumshirn @ 2016-05-11  9:40 UTC (permalink / raw)


On Tue, May 10, 2016@04:23:30PM -0600, Keith Busch wrote:
> This provides user ioctl and sysfs methods that can be used to request
> the driver rescan a controller and its namespaces. This is less harsh
> than doing a controller reset, which temporarily halts all IO just to
> surface a newly attached namespace.
> 
> This is mainly useful for controllers that implement namespace management,
> but do not support the namespace notify change asynchronous event
> notification.
> 
> Signed-off-by: Keith Busch <keith.busch at intel.com>

Reviewed-by: Johannes Thumshirn <jthumshirn at suse.de>

-- 
Johannes Thumshirn                                          Storage
jthumshirn at suse.de                                +49 911 74053 689
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 N?rnberg
GF: Felix Imend?rffer, Jane Smithard, Graham Norton
HRB 21284 (AG N?rnberg)
Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH] NVMe: User initiated rescan
  2016-05-10 22:23 [PATCH] NVMe: User initiated rescan Keith Busch
  2016-05-11  9:40 ` Johannes Thumshirn
@ 2016-05-11 19:00 ` Brandon Schulz
  2016-05-12  7:00 ` Christoph Hellwig
  2 siblings, 0 replies; 4+ messages in thread
From: Brandon Schulz @ 2016-05-11 19:00 UTC (permalink / raw)


I would like to see some version of this patch go in.  It?s useful for our pre-NVMe 1.2 devices at a minimum.

Brandon Schulz
Technologist - Systems & Software Architecture 
SSD Device Development
Western Digital Corporation
e: brandon.schulz at hgst.com
o: (507) 322-2257










On 5/10/16, 5:23 PM, "Linux-nvme on behalf of Keith Busch" <linux-nvme-bounces@lists.infradead.org on behalf of keith.busch@intel.com> wrote:

>This provides user ioctl and sysfs methods that can be used to request
>the driver rescan a controller and its namespaces. This is less harsh
>than doing a controller reset, which temporarily halts all IO just to
>surface a newly attached namespace.
>
>This is mainly useful for controllers that implement namespace management,
>but do not support the namespace notify change asynchronous event
>notification.
>
>Signed-off-by: Keith Busch <keith.busch at intel.com>
>---
> drivers/nvme/host/core.c        | 22 ++++++++++++++++++++--
> drivers/nvme/host/nvme.h        |  2 +-
> include/uapi/linux/nvme_ioctl.h |  1 +
> 3 files changed, 22 insertions(+), 3 deletions(-)
>
>diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
>index 2df0351d..b85c4b1 100644
>--- a/drivers/nvme/host/core.c
>+++ b/drivers/nvme/host/core.c
>@@ -1216,6 +1216,8 @@ static long nvme_dev_ioctl(struct file *file, unsigned int cmd,
> 		return ctrl->ops->reset_ctrl(ctrl);
> 	case NVME_IOCTL_SUBSYS_RESET:
> 		return nvme_reset_subsystem(ctrl);
>+	case NVME_IOCTL_RESCAN:
>+		return nvme_queue_scan(ctrl);
> 	default:
> 		return -ENOTTY;
> 	}
>@@ -1243,6 +1245,20 @@ static ssize_t nvme_sysfs_reset(struct device *dev,
> }
> static DEVICE_ATTR(reset_controller, S_IWUSR, NULL, nvme_sysfs_reset);
> 
>+static ssize_t nvme_sysfs_rescan(struct device *dev,
>+				struct device_attribute *attr, const char *buf,
>+				size_t count)
>+{
>+	struct nvme_ctrl *ctrl = dev_get_drvdata(dev);
>+	int ret;
>+
>+	ret = nvme_queue_scan(ctrl);
>+	if (ret < 0)
>+		return ret;
>+	return count;
>+}
>+static DEVICE_ATTR(rescan_controller, S_IWUSR, NULL, nvme_sysfs_rescan);
>+
> static ssize_t wwid_show(struct device *dev, struct device_attribute *attr,
> 								char *buf)
> {
>@@ -1346,6 +1362,7 @@ nvme_show_int_function(cntlid);
> 
> static struct attribute *nvme_dev_attrs[] = {
> 	&dev_attr_reset_controller.attr,
>+	&dev_attr_rescan_controller.attr,
> 	&dev_attr_model.attr,
> 	&dev_attr_serial.attr,
> 	&dev_attr_firmware_rev.attr,
>@@ -1569,14 +1586,15 @@ static void nvme_scan_work(struct work_struct *work)
> 		ctrl->ops->post_scan(ctrl);
> }
> 
>-void nvme_queue_scan(struct nvme_ctrl *ctrl)
>+int nvme_queue_scan(struct nvme_ctrl *ctrl)
> {
> 	/*
> 	 * Do not queue new scan work when a controller is reset during
> 	 * removal.
> 	 */
> 	if (ctrl->state == NVME_CTRL_LIVE)
>-		schedule_work(&ctrl->scan_work);
>+		return schedule_work(&ctrl->scan_work);
>+	return -EBUSY;
> }
> EXPORT_SYMBOL_GPL(nvme_queue_scan);
> 
>diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
>index 114b928..997b9ec 100644
>--- a/drivers/nvme/host/nvme.h
>+++ b/drivers/nvme/host/nvme.h
>@@ -217,7 +217,7 @@ void nvme_uninit_ctrl(struct nvme_ctrl *ctrl);
> void nvme_put_ctrl(struct nvme_ctrl *ctrl);
> int nvme_init_identify(struct nvme_ctrl *ctrl);
> 
>-void nvme_queue_scan(struct nvme_ctrl *ctrl);
>+int nvme_queue_scan(struct nvme_ctrl *ctrl);
> void nvme_remove_namespaces(struct nvme_ctrl *ctrl);
> 
> #define NVME_NR_AERS	1
>diff --git a/include/uapi/linux/nvme_ioctl.h b/include/uapi/linux/nvme_ioctl.h
>index c4b2a3f..50ff21f 100644
>--- a/include/uapi/linux/nvme_ioctl.h
>+++ b/include/uapi/linux/nvme_ioctl.h
>@@ -61,5 +61,6 @@ struct nvme_passthru_cmd {
> #define NVME_IOCTL_IO_CMD	_IOWR('N', 0x43, struct nvme_passthru_cmd)
> #define NVME_IOCTL_RESET	_IO('N', 0x44)
> #define NVME_IOCTL_SUBSYS_RESET	_IO('N', 0x45)
>+#define NVME_IOCTL_RESCAN	_IO('N', 0x46)
> 
> #endif /* _UAPI_LINUX_NVME_IOCTL_H */
>-- 
>2.7.2
>
>
>_______________________________________________
>Linux-nvme mailing list
>Linux-nvme at lists.infradead.org
>http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH] NVMe: User initiated rescan
  2016-05-10 22:23 [PATCH] NVMe: User initiated rescan Keith Busch
  2016-05-11  9:40 ` Johannes Thumshirn
  2016-05-11 19:00 ` Brandon Schulz
@ 2016-05-12  7:00 ` Christoph Hellwig
  2 siblings, 0 replies; 4+ messages in thread
From: Christoph Hellwig @ 2016-05-12  7:00 UTC (permalink / raw)


Looks fine in general, but a little nitpick below:

> -void nvme_queue_scan(struct nvme_ctrl *ctrl)
> +int nvme_queue_scan(struct nvme_ctrl *ctrl)
>  {
>  	/*
>  	 * Do not queue new scan work when a controller is reset during
>  	 * removal.
>  	 */
>  	if (ctrl->state == NVME_CTRL_LIVE)
> -		schedule_work(&ctrl->scan_work);
> +		return schedule_work(&ctrl->scan_work);
> +	return -EBUSY;

Do we really care about that EBUSY?  If the controller is being
reset it will be rescanned after that reset has completed, and if
it's removed there is no point in the error either.

Also returning schedule_work returns 1 if it successfully queue the
job, and false if it's already queued up, so you'll return something
bogus for the normal case.

I'd suggest to not return an error at all here, but if you really want to
keep the EBUSY we should at least ignore the schedule_work return
value, and write the conditional the natural way around:

	if (ctrl->state != NVME_CTRL_LIVE)
		return -EBUSY;
	schedule_work(&ctrl->scan_work);
	return 0;

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2016-05-12  7:00 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-05-10 22:23 [PATCH] NVMe: User initiated rescan Keith Busch
2016-05-11  9:40 ` Johannes Thumshirn
2016-05-11 19:00 ` Brandon Schulz
2016-05-12  7:00 ` Christoph Hellwig

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.