diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 5bd8a24be6b6..187917a4f196 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -4801,6 +4801,11 @@ Kernel parameters Example: nvme.quirks=7710:2267:bogus_nid,^identify_cns-9900:7711:broken_msi + nvme_tcp.tls_handshake_timeout= + [NVME] NVMe/TCP host TLS handshake timeout in seconds. + Valid values range from 0 to the smaller of + UINT_MAX / 1000 and MAX_JIFFY_OFFSET / HZ. Default: 10 + nvmet_tcp.tls_handshake_timeout= [NVME] NVMe/TCP target TLS handshake timeout in seconds. Valid values range from 0 to the smaller of diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c index e69e6535e1a1..a8e94e4866db 100644 --- a/drivers/nvme/host/tcp.c +++ b/drivers/nvme/host/tcp.c @@ -6,6 +6,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include #include +#include #include #include #include @@ -48,9 +49,24 @@ MODULE_PARM_DESC(wq_unbound, "Use unbound workqueue for nvme-tcp IO context (def /* * TLS handshake timeout */ -static int tls_handshake_timeout = 10; +static unsigned int tls_handshake_timeout = 10; #ifdef CONFIG_NVME_TCP_TLS -module_param(tls_handshake_timeout, int, 0644); +static int tls_handshake_timeout_set(const char *val, + const struct kernel_param *kp) +{ + return param_set_uint_minmax(val, kp, 0, + min_t(unsigned long, UINT_MAX / MSEC_PER_SEC, + MAX_JIFFY_OFFSET / HZ)); +} + +static const struct kernel_param_ops tls_handshake_timeout_ops = { + .set = tls_handshake_timeout_set, + .get = param_get_uint, +}; + +module_param_cb(tls_handshake_timeout, &tls_handshake_timeout_ops, + &tls_handshake_timeout, 0644); +__MODULE_PARM_TYPE(tls_handshake_timeout, "uint"); MODULE_PARM_DESC(tls_handshake_timeout, "nvme TLS handshake timeout in seconds (default 10)"); #endif @@ -1946,8 +1962,10 @@ static int nvme_tcp_start_tls(struct nvme_ctrl *nctrl, { int qid = nvme_tcp_queue_id(queue); int ret; + long wait_ret; struct tls_handshake_args args; - unsigned long tmo = tls_handshake_timeout * HZ; + unsigned int timeout = READ_ONCE(tls_handshake_timeout); + unsigned long tmo = (unsigned long)timeout * HZ; key_serial_t keyring = nvme_keyring_id(); dev_dbg(nctrl->device, "queue %d: start TLS with key %x\n", @@ -1961,7 +1979,7 @@ static int nvme_tcp_start_tls(struct nvme_ctrl *nctrl, if (nctrl->opts->keyring) keyring = key_serial(nctrl->opts->keyring); args.ta_keyring = keyring; - args.ta_timeout_ms = tls_handshake_timeout * 1000; + args.ta_timeout_ms = timeout * MSEC_PER_SEC; queue->tls_err = -EOPNOTSUPP; init_completion(&queue->tls_complete); ret = tls_client_hello_psk(&args, GFP_KERNEL); @@ -1970,10 +1988,10 @@ static int nvme_tcp_start_tls(struct nvme_ctrl *nctrl, qid, ret); return ret; } - ret = wait_for_completion_interruptible_timeout(&queue->tls_complete, tmo); - if (ret <= 0) { - if (ret == 0) - ret = -ETIMEDOUT; + wait_ret = wait_for_completion_interruptible_timeout(&queue->tls_complete, + tmo); + if (wait_ret <= 0) { + ret = wait_ret < 0 ? -ERESTARTSYS : -ETIMEDOUT; dev_err(nctrl->device, "queue %d: TLS handshake failed, error %d\n",