Skip to content

Commit 36d6753

Browse files
committed
Merge tag 'block-5.15-2021-09-17' of git://git.kernel.dk/linux-block
Pull block fixes from Jens Axboe: - NVMe pull request via Christoph: - fix ANA state updates when a namespace is not present (Anton Eidelman) - nvmet: fix a width vs precision bug in nvmet_subsys_attr_serial_show (Dan Carpenter) - avoid race in shutdown namespace removal (Daniel Wagner) - fix io_work priority inversion in nvme-tcp (Keith Busch) - destroy cm id before destroy qp to avoid use after free (Ruozhu Li) - blk-integrity profile registration fixes (Christoph, Lihong) - blk-cgroup UAF fix (Li) - blk-mq tag iterator fix (Ming) - blkcg memory leak fix (Yanfei) * tag 'block-5.15-2021-09-17' of git://git.kernel.dk/linux-block: blk-cgroup: fix UAF by grabbing blkcg lock before destroying blkg pd blkcg: fix memory leak in blk_iolatency_init nvme: remove the call to nvme_update_disk_info in nvme_ns_remove block: flush the integrity workqueue in blk_integrity_unregister block: check if a profile is actually registered in blk_integrity_unregister nvme-tcp: fix io_work priority inversion nvme-rdma: destroy cm id before destroy qp to avoid use after free nvme-multipath: fix ANA state updates when a namespace is not present nvme: avoid race in shutdown namespace removal nvmet: fix a width vs precision bug in nvmet_subsys_attr_serial_show() blk-mq: avoid to iterate over stale request
2 parents 7f2cd14 + 858560b commit 36d6753

File tree

8 files changed

+49
-42
lines changed

8 files changed

+49
-42
lines changed

block/blk-cgroup.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1182,10 +1182,6 @@ int blkcg_init_queue(struct request_queue *q)
11821182
if (preloaded)
11831183
radix_tree_preload_end();
11841184

1185-
ret = blk_iolatency_init(q);
1186-
if (ret)
1187-
goto err_destroy_all;
1188-
11891185
ret = blk_ioprio_init(q);
11901186
if (ret)
11911187
goto err_destroy_all;
@@ -1194,6 +1190,12 @@ int blkcg_init_queue(struct request_queue *q)
11941190
if (ret)
11951191
goto err_destroy_all;
11961192

1193+
ret = blk_iolatency_init(q);
1194+
if (ret) {
1195+
blk_throtl_exit(q);
1196+
goto err_destroy_all;
1197+
}
1198+
11971199
return 0;
11981200

11991201
err_destroy_all:
@@ -1364,10 +1366,14 @@ int blkcg_activate_policy(struct request_queue *q,
13641366
/* alloc failed, nothing's initialized yet, free everything */
13651367
spin_lock_irq(&q->queue_lock);
13661368
list_for_each_entry(blkg, &q->blkg_list, q_node) {
1369+
struct blkcg *blkcg = blkg->blkcg;
1370+
1371+
spin_lock(&blkcg->lock);
13671372
if (blkg->pd[pol->plid]) {
13681373
pol->pd_free_fn(blkg->pd[pol->plid]);
13691374
blkg->pd[pol->plid] = NULL;
13701375
}
1376+
spin_unlock(&blkcg->lock);
13711377
}
13721378
spin_unlock_irq(&q->queue_lock);
13731379
ret = -ENOMEM;
@@ -1399,12 +1405,16 @@ void blkcg_deactivate_policy(struct request_queue *q,
13991405
__clear_bit(pol->plid, q->blkcg_pols);
14001406

14011407
list_for_each_entry(blkg, &q->blkg_list, q_node) {
1408+
struct blkcg *blkcg = blkg->blkcg;
1409+
1410+
spin_lock(&blkcg->lock);
14021411
if (blkg->pd[pol->plid]) {
14031412
if (pol->pd_offline_fn)
14041413
pol->pd_offline_fn(blkg->pd[pol->plid]);
14051414
pol->pd_free_fn(blkg->pd[pol->plid]);
14061415
blkg->pd[pol->plid] = NULL;
14071416
}
1417+
spin_unlock(&blkcg->lock);
14081418
}
14091419

14101420
spin_unlock_irq(&q->queue_lock);

block/blk-integrity.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,8 +426,15 @@ EXPORT_SYMBOL(blk_integrity_register);
426426
*/
427427
void blk_integrity_unregister(struct gendisk *disk)
428428
{
429+
struct blk_integrity *bi = &disk->queue->integrity;
430+
431+
if (!bi->profile)
432+
return;
433+
434+
/* ensure all bios are off the integrity workqueue */
435+
blk_flush_integrity();
429436
blk_queue_flag_clear(QUEUE_FLAG_STABLE_WRITES, disk->queue);
430-
memset(&disk->queue->integrity, 0, sizeof(struct blk_integrity));
437+
memset(bi, 0, sizeof(*bi));
431438
}
432439
EXPORT_SYMBOL(blk_integrity_unregister);
433440

block/blk-mq-tag.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ static struct request *blk_mq_find_and_get_req(struct blk_mq_tags *tags,
208208

209209
spin_lock_irqsave(&tags->lock, flags);
210210
rq = tags->rqs[bitnr];
211-
if (!rq || !refcount_inc_not_zero(&rq->ref))
211+
if (!rq || rq->tag != bitnr || !refcount_inc_not_zero(&rq->ref))
212212
rq = NULL;
213213
spin_unlock_irqrestore(&tags->lock, flags);
214214
return rq;

drivers/nvme/host/core.c

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3524,7 +3524,9 @@ static struct nvme_ns_head *nvme_find_ns_head(struct nvme_subsystem *subsys,
35243524
lockdep_assert_held(&subsys->lock);
35253525

35263526
list_for_each_entry(h, &subsys->nsheads, entry) {
3527-
if (h->ns_id == nsid && nvme_tryget_ns_head(h))
3527+
if (h->ns_id != nsid)
3528+
continue;
3529+
if (!list_empty(&h->list) && nvme_tryget_ns_head(h))
35283530
return h;
35293531
}
35303532

@@ -3843,6 +3845,10 @@ static void nvme_ns_remove(struct nvme_ns *ns)
38433845

38443846
mutex_lock(&ns->ctrl->subsys->lock);
38453847
list_del_rcu(&ns->siblings);
3848+
if (list_empty(&ns->head->list)) {
3849+
list_del_init(&ns->head->entry);
3850+
last_path = true;
3851+
}
38463852
mutex_unlock(&ns->ctrl->subsys->lock);
38473853

38483854
/* guarantee not available in head->list */
@@ -3856,20 +3862,11 @@ static void nvme_ns_remove(struct nvme_ns *ns)
38563862
nvme_cdev_del(&ns->cdev, &ns->cdev_device);
38573863
del_gendisk(ns->disk);
38583864
blk_cleanup_queue(ns->queue);
3859-
if (blk_get_integrity(ns->disk))
3860-
blk_integrity_unregister(ns->disk);
38613865

38623866
down_write(&ns->ctrl->namespaces_rwsem);
38633867
list_del_init(&ns->list);
38643868
up_write(&ns->ctrl->namespaces_rwsem);
38653869

3866-
/* Synchronize with nvme_init_ns_head() */
3867-
mutex_lock(&ns->head->subsys->lock);
3868-
if (list_empty(&ns->head->list)) {
3869-
list_del_init(&ns->head->entry);
3870-
last_path = true;
3871-
}
3872-
mutex_unlock(&ns->head->subsys->lock);
38733870
if (last_path)
38743871
nvme_mpath_shutdown_disk(ns->head);
38753872
nvme_put_ns(ns);

drivers/nvme/host/multipath.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -600,14 +600,17 @@ static int nvme_update_ana_state(struct nvme_ctrl *ctrl,
600600

601601
down_read(&ctrl->namespaces_rwsem);
602602
list_for_each_entry(ns, &ctrl->namespaces, list) {
603-
unsigned nsid = le32_to_cpu(desc->nsids[n]);
604-
603+
unsigned nsid;
604+
again:
605+
nsid = le32_to_cpu(desc->nsids[n]);
605606
if (ns->head->ns_id < nsid)
606607
continue;
607608
if (ns->head->ns_id == nsid)
608609
nvme_update_ns_ana_state(desc, ns);
609610
if (++n == nr_nsids)
610611
break;
612+
if (ns->head->ns_id > nsid)
613+
goto again;
611614
}
612615
up_read(&ctrl->namespaces_rwsem);
613616
return 0;

drivers/nvme/host/rdma.c

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -656,8 +656,8 @@ static void nvme_rdma_free_queue(struct nvme_rdma_queue *queue)
656656
if (!test_and_clear_bit(NVME_RDMA_Q_ALLOCATED, &queue->flags))
657657
return;
658658

659-
nvme_rdma_destroy_queue_ib(queue);
660659
rdma_destroy_id(queue->cm_id);
660+
nvme_rdma_destroy_queue_ib(queue);
661661
mutex_destroy(&queue->queue_lock);
662662
}
663663

@@ -1815,14 +1815,10 @@ static int nvme_rdma_conn_established(struct nvme_rdma_queue *queue)
18151815
for (i = 0; i < queue->queue_size; i++) {
18161816
ret = nvme_rdma_post_recv(queue, &queue->rsp_ring[i]);
18171817
if (ret)
1818-
goto out_destroy_queue_ib;
1818+
return ret;
18191819
}
18201820

18211821
return 0;
1822-
1823-
out_destroy_queue_ib:
1824-
nvme_rdma_destroy_queue_ib(queue);
1825-
return ret;
18261822
}
18271823

18281824
static int nvme_rdma_conn_rejected(struct nvme_rdma_queue *queue,
@@ -1916,14 +1912,10 @@ static int nvme_rdma_route_resolved(struct nvme_rdma_queue *queue)
19161912
if (ret) {
19171913
dev_err(ctrl->ctrl.device,
19181914
"rdma_connect_locked failed (%d).\n", ret);
1919-
goto out_destroy_queue_ib;
1915+
return ret;
19201916
}
19211917

19221918
return 0;
1923-
1924-
out_destroy_queue_ib:
1925-
nvme_rdma_destroy_queue_ib(queue);
1926-
return ret;
19271919
}
19281920

19291921
static int nvme_rdma_cm_handler(struct rdma_cm_id *cm_id,
@@ -1954,8 +1946,6 @@ static int nvme_rdma_cm_handler(struct rdma_cm_id *cm_id,
19541946
case RDMA_CM_EVENT_ROUTE_ERROR:
19551947
case RDMA_CM_EVENT_CONNECT_ERROR:
19561948
case RDMA_CM_EVENT_UNREACHABLE:
1957-
nvme_rdma_destroy_queue_ib(queue);
1958-
fallthrough;
19591949
case RDMA_CM_EVENT_ADDR_ERROR:
19601950
dev_dbg(queue->ctrl->ctrl.device,
19611951
"CM error event %d\n", ev->event);

drivers/nvme/host/tcp.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,12 @@ static inline void nvme_tcp_send_all(struct nvme_tcp_queue *queue)
274274
} while (ret > 0);
275275
}
276276

277+
static inline bool nvme_tcp_queue_more(struct nvme_tcp_queue *queue)
278+
{
279+
return !list_empty(&queue->send_list) ||
280+
!llist_empty(&queue->req_list) || queue->more_requests;
281+
}
282+
277283
static inline void nvme_tcp_queue_request(struct nvme_tcp_request *req,
278284
bool sync, bool last)
279285
{
@@ -294,9 +300,10 @@ static inline void nvme_tcp_queue_request(struct nvme_tcp_request *req,
294300
nvme_tcp_send_all(queue);
295301
queue->more_requests = false;
296302
mutex_unlock(&queue->send_mutex);
297-
} else if (last) {
298-
queue_work_on(queue->io_cpu, nvme_tcp_wq, &queue->io_work);
299303
}
304+
305+
if (last && nvme_tcp_queue_more(queue))
306+
queue_work_on(queue->io_cpu, nvme_tcp_wq, &queue->io_work);
300307
}
301308

302309
static void nvme_tcp_process_req_list(struct nvme_tcp_queue *queue)
@@ -906,12 +913,6 @@ static void nvme_tcp_state_change(struct sock *sk)
906913
read_unlock_bh(&sk->sk_callback_lock);
907914
}
908915

909-
static inline bool nvme_tcp_queue_more(struct nvme_tcp_queue *queue)
910-
{
911-
return !list_empty(&queue->send_list) ||
912-
!llist_empty(&queue->req_list) || queue->more_requests;
913-
}
914-
915916
static inline void nvme_tcp_done_send_req(struct nvme_tcp_queue *queue)
916917
{
917918
queue->request = NULL;
@@ -1145,8 +1146,7 @@ static void nvme_tcp_io_work(struct work_struct *w)
11451146
pending = true;
11461147
else if (unlikely(result < 0))
11471148
break;
1148-
} else
1149-
pending = !llist_empty(&queue->req_list);
1149+
}
11501150

11511151
result = nvme_tcp_try_recv(queue);
11521152
if (result > 0)

drivers/nvme/target/configfs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1067,7 +1067,7 @@ static ssize_t nvmet_subsys_attr_serial_show(struct config_item *item,
10671067
{
10681068
struct nvmet_subsys *subsys = to_subsys(item);
10691069

1070-
return snprintf(page, PAGE_SIZE, "%*s\n",
1070+
return snprintf(page, PAGE_SIZE, "%.*s\n",
10711071
NVMET_SN_MAX_SIZE, subsys->serial);
10721072
}
10731073

0 commit comments

Comments
 (0)