nvme: send a rediscover uevent when a persistent discovery controller reconnects
authorSagi Grimberg <sagi@grimberg.me>
Thu, 22 Sep 2022 08:15:37 +0000 (11:15 +0300)
committerChristoph Hellwig <hch@lst.de>
Tue, 27 Sep 2022 07:22:07 +0000 (09:22 +0200)
When a discovery controller is disconnected, no AENs will arrive to
notify the host about discovery log change events.

In order to solve this, send a uevent notification when a
persistent discovery controller reconnects. We add a new ctrl
flag NVME_CTRL_STARTED_ONCE that will be set on the first
start, and consecutive calls will find it set, and send the
event to userspace if the controller is a discovery controller.

Upon the event reception, userspace will re-read the discovery
log page and will act upon changes as it sees fit.

Signed-off-by: Sagi Grimberg <sagi@grimberg.me>
Reviewed-by: Daniel Wagner <dwagner@suse.de>
Reviewed-by: James Smart <jsmart2021@gmail.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
drivers/nvme/host/core.c
drivers/nvme/host/nvme.h

index e56ecc7fda2d976d8782c478ecacec948b1026f1..0de2c227c1ab54114c07cd68b8efc6d2caa3adb3 100644 (file)
@@ -4815,6 +4815,16 @@ void nvme_start_ctrl(struct nvme_ctrl *ctrl)
 
        nvme_enable_aen(ctrl);
 
+       /*
+        * persistent discovery controllers need to send indication to userspace
+        * to re-read the discovery log page to learn about possible changes
+        * that were missed. We identify persistent discovery controllers by
+        * checking that they started once before, hence are reconnecting back.
+        */
+       if (test_and_set_bit(NVME_CTRL_STARTED_ONCE, &ctrl->flags) &&
+           nvme_discovery_ctrl(ctrl))
+               nvme_change_uevent(ctrl, "NVME_EVENT=rediscover");
+
        if (ctrl->queue_count > 1) {
                nvme_queue_scan(ctrl);
                nvme_start_queues(ctrl);
index 6b4984e8b36399cc49a818d6abfd29c0fb9f8dc7..a8b054cd2ebbd2a818045619c5016cebc263f091 100644 (file)
@@ -236,6 +236,7 @@ struct nvme_fault_inject {
 enum nvme_ctrl_flags {
        NVME_CTRL_FAILFAST_EXPIRED      = 0,
        NVME_CTRL_ADMIN_Q_STOPPED       = 1,
+       NVME_CTRL_STARTED_ONCE          = 2,
 };
 
 struct nvme_ctrl {