Page MenuHomeFreeBSD

D45308.1794832312.diff
No OneTemporary

Authored By
Unknown
Size
4 KB
Referenced Files
None
Subscribers
None

D45308.1794832312.diff

diff --git a/share/man/man4/nvmf.4 b/share/man/man4/nvmf.4
--- a/share/man/man4/nvmf.4
+++ b/share/man/man4/nvmf.4
@@ -3,7 +3,7 @@
.\"
.\" Copyright (c) 2024 Chelsio Communications, Inc.
.\"
-.Dd May 2, 2024
+.Dd June 5, 2024
.Dt NVMF 4
.Os
.Sh NAME
@@ -65,6 +65,28 @@
Associations require a supported transport such as
.Xr nvmf_tcp 4
for associations using TCP/IP.
+.Sh SYSCTL VARIABLES
+The following variables are available as both
+.Xr sysctl 8
+variables and
+.Xr loader 8
+tunables:
+.Bl -tag -width indent
+.It Va kern.nvmf.fail_on_disconnection
+Determines the behavior when an association's connection is interrupted.
+By default, input/output operations are suspended while a host is disconnected.
+This includes operations pending at the time the association's connection was
+interrupted as well as new requests submitted while the host is disconnected.
+Once a new association is established, suspended I/O requests are retried.
+When set to 1, input/output operations fail with
+.Er EIO
+while a host is disconnected and
+.Xr nda 4
+peripherals are destroyed after the first failed I/O request.
+Note that any destroyed
+.Xr nda 4
+peripherals will be recreated after a new association is established.
+.El
.Sh SEE ALSO
.Xr nda 4 ,
.Xr nvme 4 ,
diff --git a/sys/dev/nvmf/host/nvmf.c b/sys/dev/nvmf/host/nvmf.c
--- a/sys/dev/nvmf/host/nvmf.c
+++ b/sys/dev/nvmf/host/nvmf.c
@@ -15,6 +15,7 @@
#include <sys/module.h>
#include <sys/mutex.h>
#include <sys/sx.h>
+#include <sys/sysctl.h>
#include <sys/taskqueue.h>
#include <dev/nvme/nvme.h>
#include <dev/nvmf/nvmf.h>
@@ -23,6 +24,10 @@
static struct cdevsw nvmf_cdevsw;
+bool nvmf_fail_disconnect = false;
+SYSCTL_BOOL(_kern_nvmf, OID_AUTO, fail_on_disconnection, CTLFLAG_RWTUN,
+ &nvmf_fail_disconnect, 0, "Fail I/O requests on connection failure");
+
MALLOC_DEFINE(M_NVMF, "nvmf", "NVMe over Fabrics host");
static void nvmf_disconnect_task(void *arg, int pending);
diff --git a/sys/dev/nvmf/host/nvmf_ns.c b/sys/dev/nvmf/host/nvmf_ns.c
--- a/sys/dev/nvmf/host/nvmf_ns.c
+++ b/sys/dev/nvmf/host/nvmf_ns.c
@@ -84,13 +84,22 @@
ns = bio->bio_dev->si_drv1;
/* If a request is aborted, resubmit or queue it for resubmission. */
- if (bio->bio_error == ECONNABORTED) {
+ if (bio->bio_error == ECONNABORTED && !nvmf_fail_disconnect) {
bio->bio_error = 0;
bio->bio_driver2 = 0;
mtx_lock(&ns->lock);
if (ns->disconnected) {
- TAILQ_INSERT_TAIL(&ns->pending_bios, bio, bio_queue);
- mtx_unlock(&ns->lock);
+ if (nvmf_fail_disconnect) {
+ mtx_unlock(&ns->lock);
+ bio->bio_error = ECONNABORTED;
+ bio->bio_flags |= BIO_ERROR;
+ bio->bio_resid = bio->bio_bcount;
+ biodone(bio);
+ } else {
+ TAILQ_INSERT_TAIL(&ns->pending_bios, bio,
+ bio_queue);
+ mtx_unlock(&ns->lock);
+ }
} else {
mtx_unlock(&ns->lock);
nvmf_ns_strategy(bio);
@@ -163,6 +172,7 @@
struct nvme_dsm_range *dsm_range;
struct memdesc mem;
uint64_t lba, lba_count;
+ int error;
dsm_range = NULL;
memset(&cmd, 0, sizeof(cmd));
@@ -201,10 +211,15 @@
mtx_lock(&ns->lock);
if (ns->disconnected) {
- TAILQ_INSERT_TAIL(&ns->pending_bios, bio, bio_queue);
+ if (nvmf_fail_disconnect) {
+ error = ECONNABORTED;
+ } else {
+ TAILQ_INSERT_TAIL(&ns->pending_bios, bio, bio_queue);
+ error = 0;
+ }
mtx_unlock(&ns->lock);
free(dsm_range, M_NVMF);
- return (0);
+ return (error);
}
req = nvmf_allocate_request(nvmf_select_io_queue(ns->sc), &cmd,
diff --git a/sys/dev/nvmf/host/nvmf_sim.c b/sys/dev/nvmf/host/nvmf_sim.c
--- a/sys/dev/nvmf/host/nvmf_sim.c
+++ b/sys/dev/nvmf/host/nvmf_sim.c
@@ -40,7 +40,10 @@
return;
if (nvmf_cqe_aborted(&ccb->nvmeio.cpl)) {
- ccb->ccb_h.status = CAM_REQUEUE_REQ;
+ if (nvmf_fail_disconnect)
+ ccb->ccb_h.status = CAM_DEV_NOT_THERE;
+ else
+ ccb->ccb_h.status = CAM_REQUEUE_REQ;
xpt_done(ccb);
} else if (ccb->nvmeio.cpl.status != 0) {
ccb->ccb_h.status = CAM_NVME_STATUS_ERROR;
@@ -106,7 +109,10 @@
mtx_lock(&sc->sim_mtx);
if (sc->sim_disconnected) {
mtx_unlock(&sc->sim_mtx);
- nvmeio->ccb_h.status = CAM_REQUEUE_REQ;
+ if (nvmf_fail_disconnect)
+ nvmeio->ccb_h.status = CAM_DEV_NOT_THERE;
+ else
+ nvmeio->ccb_h.status = CAM_REQUEUE_REQ;
xpt_done(ccb);
return;
}
diff --git a/sys/dev/nvmf/host/nvmf_var.h b/sys/dev/nvmf/host/nvmf_var.h
--- a/sys/dev/nvmf/host/nvmf_var.h
+++ b/sys/dev/nvmf/host/nvmf_var.h
@@ -140,6 +140,9 @@
MALLOC_DECLARE(M_NVMF);
#endif
+/* If true, I/O requests will fail while the host is disconnected. */
+extern bool nvmf_fail_disconnect;
+
/* nvmf.c */
void nvmf_complete(void *arg, const struct nvme_completion *cqe);
void nvmf_io_complete(void *arg, size_t xfered, int error);

File Metadata

Mime Type
text/plain
Expires
Mon, Nov 16, 12:31 PM (20 h, 48 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
41777069
Default Alt Text
D45308.1794832312.diff (4 KB)

Event Timeline