Skip to content

Commit ec9b3ac

Browse files
committed
Merge tag 'nvme-6.13-2024-11-21' of git://git.infradead.org/nvme into for-6.13/block
Pull NVMe updates from Keith: "nvme updates for Linux 6.13 - Use correct srcu list traversal (Breno) - Scatter-gather support for metadata (Keith) - Fabrics shutdown race condition fix (Nilay) - Persistent reservations updates (Guixin)" * tag 'nvme-6.13-2024-11-21' of git://git.infradead.org/nvme: nvme: tuning pr code by using defined structs and macros nvme: introduce change ptpl and iekey definition nvme-fabrics: fix kernel crash while shutting down controller Revert "nvme: make keep-alive synchronous operation" nvme-pci: use sgls for all user requests if possible nvme: define the remaining used sgls constants nvme-pci: add support for sgl metadata nvme/multipath: Fix RCU list traversal to use SRCU primitive
2 parents 766a71e + 029cc98 commit ec9b3ac

File tree

9 files changed

+274
-85
lines changed

9 files changed

+274
-85
lines changed

drivers/nvme/host/core.c

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1294,9 +1294,10 @@ static void nvme_queue_keep_alive_work(struct nvme_ctrl *ctrl)
12941294
queue_delayed_work(nvme_wq, &ctrl->ka_work, delay);
12951295
}
12961296

1297-
static void nvme_keep_alive_finish(struct request *rq,
1298-
blk_status_t status, struct nvme_ctrl *ctrl)
1297+
static enum rq_end_io_ret nvme_keep_alive_end_io(struct request *rq,
1298+
blk_status_t status)
12991299
{
1300+
struct nvme_ctrl *ctrl = rq->end_io_data;
13001301
unsigned long rtt = jiffies - (rq->deadline - rq->timeout);
13011302
unsigned long delay = nvme_keep_alive_work_period(ctrl);
13021303
enum nvme_ctrl_state state = nvme_ctrl_state(ctrl);
@@ -1313,17 +1314,20 @@ static void nvme_keep_alive_finish(struct request *rq,
13131314
delay = 0;
13141315
}
13151316

1317+
blk_mq_free_request(rq);
1318+
13161319
if (status) {
13171320
dev_err(ctrl->device,
13181321
"failed nvme_keep_alive_end_io error=%d\n",
13191322
status);
1320-
return;
1323+
return RQ_END_IO_NONE;
13211324
}
13221325

13231326
ctrl->ka_last_check_time = jiffies;
13241327
ctrl->comp_seen = false;
13251328
if (state == NVME_CTRL_LIVE || state == NVME_CTRL_CONNECTING)
13261329
queue_delayed_work(nvme_wq, &ctrl->ka_work, delay);
1330+
return RQ_END_IO_NONE;
13271331
}
13281332

13291333
static void nvme_keep_alive_work(struct work_struct *work)
@@ -1332,7 +1336,6 @@ static void nvme_keep_alive_work(struct work_struct *work)
13321336
struct nvme_ctrl, ka_work);
13331337
bool comp_seen = ctrl->comp_seen;
13341338
struct request *rq;
1335-
blk_status_t status;
13361339

13371340
ctrl->ka_last_check_time = jiffies;
13381341

@@ -1355,9 +1358,9 @@ static void nvme_keep_alive_work(struct work_struct *work)
13551358
nvme_init_request(rq, &ctrl->ka_cmd);
13561359

13571360
rq->timeout = ctrl->kato * HZ;
1358-
status = blk_execute_rq(rq, false);
1359-
nvme_keep_alive_finish(rq, status, ctrl);
1360-
blk_mq_free_request(rq);
1361+
rq->end_io = nvme_keep_alive_end_io;
1362+
rq->end_io_data = ctrl;
1363+
blk_execute_rq_nowait(rq, false);
13611364
}
13621365

13631366
static void nvme_start_keep_alive(struct nvme_ctrl *ctrl)
@@ -4571,6 +4574,11 @@ EXPORT_SYMBOL_GPL(nvme_alloc_admin_tag_set);
45714574

45724575
void nvme_remove_admin_tag_set(struct nvme_ctrl *ctrl)
45734576
{
4577+
/*
4578+
* As we're about to destroy the queue and free tagset
4579+
* we can not have keep-alive work running.
4580+
*/
4581+
nvme_stop_keep_alive(ctrl);
45744582
blk_mq_destroy_queue(ctrl->admin_q);
45754583
blk_put_queue(ctrl->admin_q);
45764584
if (ctrl->ops->flags & NVME_F_FABRICS) {

drivers/nvme/host/ioctl.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,12 +120,20 @@ static int nvme_map_user_request(struct request *req, u64 ubuffer,
120120
struct nvme_ns *ns = q->queuedata;
121121
struct block_device *bdev = ns ? ns->disk->part0 : NULL;
122122
bool supports_metadata = bdev && blk_get_integrity(bdev->bd_disk);
123+
struct nvme_ctrl *ctrl = nvme_req(req)->ctrl;
123124
bool has_metadata = meta_buffer && meta_len;
124125
struct bio *bio = NULL;
125126
int ret;
126127

127-
if (has_metadata && !supports_metadata)
128-
return -EINVAL;
128+
if (!nvme_ctrl_sgl_supported(ctrl))
129+
dev_warn_once(ctrl->device, "using unchecked data buffer\n");
130+
if (has_metadata) {
131+
if (!supports_metadata)
132+
return -EINVAL;
133+
if (!nvme_ctrl_meta_sgl_supported(ctrl))
134+
dev_warn_once(ctrl->device,
135+
"using unchecked metadata buffer\n");
136+
}
129137

130138
if (ioucmd && (ioucmd->flags & IORING_URING_CMD_FIXED)) {
131139
struct iov_iter iter;

drivers/nvme/host/multipath.c

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,8 @@ void nvme_kick_requeue_lists(struct nvme_ctrl *ctrl)
165165
int srcu_idx;
166166

167167
srcu_idx = srcu_read_lock(&ctrl->srcu);
168-
list_for_each_entry_rcu(ns, &ctrl->namespaces, list) {
168+
list_for_each_entry_srcu(ns, &ctrl->namespaces, list,
169+
srcu_read_lock_held(&ctrl->srcu)) {
169170
if (!ns->head->disk)
170171
continue;
171172
kblockd_schedule_work(&ns->head->requeue_work);
@@ -209,7 +210,8 @@ void nvme_mpath_clear_ctrl_paths(struct nvme_ctrl *ctrl)
209210
int srcu_idx;
210211

211212
srcu_idx = srcu_read_lock(&ctrl->srcu);
212-
list_for_each_entry_rcu(ns, &ctrl->namespaces, list) {
213+
list_for_each_entry_srcu(ns, &ctrl->namespaces, list,
214+
srcu_read_lock_held(&ctrl->srcu)) {
213215
nvme_mpath_clear_current_path(ns);
214216
kblockd_schedule_work(&ns->head->requeue_work);
215217
}
@@ -224,7 +226,8 @@ void nvme_mpath_revalidate_paths(struct nvme_ns *ns)
224226
int srcu_idx;
225227

226228
srcu_idx = srcu_read_lock(&head->srcu);
227-
list_for_each_entry_rcu(ns, &head->list, siblings) {
229+
list_for_each_entry_srcu(ns, &head->list, siblings,
230+
srcu_read_lock_held(&head->srcu)) {
228231
if (capacity != get_capacity(ns->disk))
229232
clear_bit(NVME_NS_READY, &ns->flags);
230233
}
@@ -257,7 +260,8 @@ static struct nvme_ns *__nvme_find_path(struct nvme_ns_head *head, int node)
257260
int found_distance = INT_MAX, fallback_distance = INT_MAX, distance;
258261
struct nvme_ns *found = NULL, *fallback = NULL, *ns;
259262

260-
list_for_each_entry_rcu(ns, &head->list, siblings) {
263+
list_for_each_entry_srcu(ns, &head->list, siblings,
264+
srcu_read_lock_held(&head->srcu)) {
261265
if (nvme_path_is_disabled(ns))
262266
continue;
263267

@@ -356,7 +360,8 @@ static struct nvme_ns *nvme_queue_depth_path(struct nvme_ns_head *head)
356360
unsigned int min_depth_opt = UINT_MAX, min_depth_nonopt = UINT_MAX;
357361
unsigned int depth;
358362

359-
list_for_each_entry_rcu(ns, &head->list, siblings) {
363+
list_for_each_entry_srcu(ns, &head->list, siblings,
364+
srcu_read_lock_held(&head->srcu)) {
360365
if (nvme_path_is_disabled(ns))
361366
continue;
362367

@@ -424,7 +429,8 @@ static bool nvme_available_path(struct nvme_ns_head *head)
424429
if (!test_bit(NVME_NSHEAD_DISK_LIVE, &head->flags))
425430
return NULL;
426431

427-
list_for_each_entry_rcu(ns, &head->list, siblings) {
432+
list_for_each_entry_srcu(ns, &head->list, siblings,
433+
srcu_read_lock_held(&head->srcu)) {
428434
if (test_bit(NVME_CTRL_FAILFAST_EXPIRED, &ns->ctrl->flags))
429435
continue;
430436
switch (nvme_ctrl_state(ns->ctrl)) {
@@ -783,7 +789,8 @@ static int nvme_update_ana_state(struct nvme_ctrl *ctrl,
783789
return 0;
784790

785791
srcu_idx = srcu_read_lock(&ctrl->srcu);
786-
list_for_each_entry_rcu(ns, &ctrl->namespaces, list) {
792+
list_for_each_entry_srcu(ns, &ctrl->namespaces, list,
793+
srcu_read_lock_held(&ctrl->srcu)) {
787794
unsigned nsid;
788795
again:
789796
nsid = le32_to_cpu(desc->nsids[n]);

drivers/nvme/host/nvme.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1123,7 +1123,15 @@ static inline void nvme_start_request(struct request *rq)
11231123

11241124
static inline bool nvme_ctrl_sgl_supported(struct nvme_ctrl *ctrl)
11251125
{
1126-
return ctrl->sgls & ((1 << 0) | (1 << 1));
1126+
return ctrl->sgls & (NVME_CTRL_SGLS_BYTE_ALIGNED |
1127+
NVME_CTRL_SGLS_DWORD_ALIGNED);
1128+
}
1129+
1130+
static inline bool nvme_ctrl_meta_sgl_supported(struct nvme_ctrl *ctrl)
1131+
{
1132+
if (ctrl->ops->flags & NVME_F_FABRICS)
1133+
return true;
1134+
return ctrl->sgls & NVME_CTRL_SGLS_MSDS;
11271135
}
11281136

11291137
#ifdef CONFIG_NVME_HOST_AUTH

0 commit comments

Comments
 (0)