Skip to content

Commit a379fbb

Browse files
committed
Merge tag 'block-5.15-2021-10-29' of git://git.kernel.dk/linux-block
Pull block fixes from Jens Axboe: - NVMe pull request: - fix nvmet-tcp header digest verification (Amit Engel) - fix a memory leak in nvmet-tcp when releasing a queue (Maurizio Lombardi) - fix nvme-tcp H2CData PDU send accounting again (Sagi Grimberg) - fix digest pointer calculation in nvme-tcp and nvmet-tcp (Varun Prakash) - fix possible nvme-tcp req->offset corruption (Varun Prakash) - Queue drain ordering fix (Ming) - Partition check regression for zoned devices (Shin'ichiro) - Zone queue restart fix (Naohiro) * tag 'block-5.15-2021-10-29' of git://git.kernel.dk/linux-block: block: Fix partition check for host-aware zoned block devices nvmet-tcp: fix header digest verification nvmet-tcp: fix data digest pointer calculation nvme-tcp: fix data digest pointer calculation nvme-tcp: fix possible req->offset corruption block: schedule queue restart after BLK_STS_ZONE_RESOURCE block: drain queue after disk is removed from sysfs nvme-tcp: fix H2CData PDU send accounting (again) nvmet-tcp: fix a memory leak when releasing a queue
2 parents 17d50f8 + f4aaf1f commit a379fbb

File tree

5 files changed

+51
-20
lines changed

5 files changed

+51
-20
lines changed

block/blk-mq.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1325,6 +1325,7 @@ bool blk_mq_dispatch_rq_list(struct blk_mq_hw_ctx *hctx, struct list_head *list,
13251325
int errors, queued;
13261326
blk_status_t ret = BLK_STS_OK;
13271327
LIST_HEAD(zone_list);
1328+
bool needs_resource = false;
13281329

13291330
if (list_empty(list))
13301331
return false;
@@ -1370,6 +1371,8 @@ bool blk_mq_dispatch_rq_list(struct blk_mq_hw_ctx *hctx, struct list_head *list,
13701371
queued++;
13711372
break;
13721373
case BLK_STS_RESOURCE:
1374+
needs_resource = true;
1375+
fallthrough;
13731376
case BLK_STS_DEV_RESOURCE:
13741377
blk_mq_handle_dev_resource(rq, list);
13751378
goto out;
@@ -1380,6 +1383,7 @@ bool blk_mq_dispatch_rq_list(struct blk_mq_hw_ctx *hctx, struct list_head *list,
13801383
* accept.
13811384
*/
13821385
blk_mq_handle_zone_resource(rq, &zone_list);
1386+
needs_resource = true;
13831387
break;
13841388
default:
13851389
errors++;
@@ -1406,7 +1410,6 @@ bool blk_mq_dispatch_rq_list(struct blk_mq_hw_ctx *hctx, struct list_head *list,
14061410
/* For non-shared tags, the RESTART check will suffice */
14071411
bool no_tag = prep == PREP_DISPATCH_NO_TAG &&
14081412
(hctx->flags & BLK_MQ_F_TAG_QUEUE_SHARED);
1409-
bool no_budget_avail = prep == PREP_DISPATCH_NO_BUDGET;
14101413

14111414
if (nr_budgets)
14121415
blk_mq_release_budgets(q, list);
@@ -1447,14 +1450,16 @@ bool blk_mq_dispatch_rq_list(struct blk_mq_hw_ctx *hctx, struct list_head *list,
14471450
* If driver returns BLK_STS_RESOURCE and SCHED_RESTART
14481451
* bit is set, run queue after a delay to avoid IO stalls
14491452
* that could otherwise occur if the queue is idle. We'll do
1450-
* similar if we couldn't get budget and SCHED_RESTART is set.
1453+
* similar if we couldn't get budget or couldn't lock a zone
1454+
* and SCHED_RESTART is set.
14511455
*/
14521456
needs_restart = blk_mq_sched_needs_restart(hctx);
1457+
if (prep == PREP_DISPATCH_NO_BUDGET)
1458+
needs_resource = true;
14531459
if (!needs_restart ||
14541460
(no_tag && list_empty_careful(&hctx->dispatch_wait.entry)))
14551461
blk_mq_run_hw_queue(hctx, true);
1456-
else if (needs_restart && (ret == BLK_STS_RESOURCE ||
1457-
no_budget_avail))
1462+
else if (needs_restart && needs_resource)
14581463
blk_mq_delay_run_hw_queue(hctx, BLK_MQ_RESOURCE_DELAY);
14591464

14601465
blk_mq_update_dispatch_busy(hctx, true);

block/blk-settings.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -842,6 +842,24 @@ bool blk_queue_can_use_dma_map_merging(struct request_queue *q,
842842
}
843843
EXPORT_SYMBOL_GPL(blk_queue_can_use_dma_map_merging);
844844

845+
static bool disk_has_partitions(struct gendisk *disk)
846+
{
847+
unsigned long idx;
848+
struct block_device *part;
849+
bool ret = false;
850+
851+
rcu_read_lock();
852+
xa_for_each(&disk->part_tbl, idx, part) {
853+
if (bdev_is_partition(part)) {
854+
ret = true;
855+
break;
856+
}
857+
}
858+
rcu_read_unlock();
859+
860+
return ret;
861+
}
862+
845863
/**
846864
* blk_queue_set_zoned - configure a disk queue zoned model.
847865
* @disk: the gendisk of the queue to configure
@@ -876,7 +894,7 @@ void blk_queue_set_zoned(struct gendisk *disk, enum blk_zoned_model model)
876894
* we do nothing special as far as the block layer is concerned.
877895
*/
878896
if (!IS_ENABLED(CONFIG_BLK_DEV_ZONED) ||
879-
!xa_empty(&disk->part_tbl))
897+
disk_has_partitions(disk))
880898
model = BLK_ZONED_NONE;
881899
break;
882900
case BLK_ZONED_NONE:

block/genhd.c

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -588,16 +588,6 @@ void del_gendisk(struct gendisk *disk)
588588
* Prevent new I/O from crossing bio_queue_enter().
589589
*/
590590
blk_queue_start_drain(q);
591-
blk_mq_freeze_queue_wait(q);
592-
593-
rq_qos_exit(q);
594-
blk_sync_queue(q);
595-
blk_flush_integrity();
596-
/*
597-
* Allow using passthrough request again after the queue is torn down.
598-
*/
599-
blk_queue_flag_clear(QUEUE_FLAG_INIT_DONE, q);
600-
__blk_mq_unfreeze_queue(q, true);
601591

602592
if (!(disk->flags & GENHD_FL_HIDDEN)) {
603593
sysfs_remove_link(&disk_to_dev(disk)->kobj, "bdi");
@@ -620,6 +610,18 @@ void del_gendisk(struct gendisk *disk)
620610
sysfs_remove_link(block_depr, dev_name(disk_to_dev(disk)));
621611
pm_runtime_set_memalloc_noio(disk_to_dev(disk), false);
622612
device_del(disk_to_dev(disk));
613+
614+
blk_mq_freeze_queue_wait(q);
615+
616+
rq_qos_exit(q);
617+
blk_sync_queue(q);
618+
blk_flush_integrity();
619+
/*
620+
* Allow using passthrough request again after the queue is torn down.
621+
*/
622+
blk_queue_flag_clear(QUEUE_FLAG_INIT_DONE, q);
623+
__blk_mq_unfreeze_queue(q, true);
624+
623625
}
624626
EXPORT_SYMBOL(del_gendisk);
625627

drivers/nvme/host/tcp.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -926,12 +926,14 @@ static void nvme_tcp_fail_request(struct nvme_tcp_request *req)
926926
static int nvme_tcp_try_send_data(struct nvme_tcp_request *req)
927927
{
928928
struct nvme_tcp_queue *queue = req->queue;
929+
int req_data_len = req->data_len;
929930

930931
while (true) {
931932
struct page *page = nvme_tcp_req_cur_page(req);
932933
size_t offset = nvme_tcp_req_cur_offset(req);
933934
size_t len = nvme_tcp_req_cur_length(req);
934935
bool last = nvme_tcp_pdu_last_send(req, len);
936+
int req_data_sent = req->data_sent;
935937
int ret, flags = MSG_DONTWAIT;
936938

937939
if (last && !queue->data_digest && !nvme_tcp_queue_more(queue))
@@ -958,7 +960,7 @@ static int nvme_tcp_try_send_data(struct nvme_tcp_request *req)
958960
* in the request where we don't want to modify it as we may
959961
* compete with the RX path completing the request.
960962
*/
961-
if (req->data_sent + ret < req->data_len)
963+
if (req_data_sent + ret < req_data_len)
962964
nvme_tcp_advance_req(req, ret);
963965

964966
/* fully successful last send in current PDU */
@@ -1048,10 +1050,11 @@ static int nvme_tcp_try_send_data_pdu(struct nvme_tcp_request *req)
10481050
static int nvme_tcp_try_send_ddgst(struct nvme_tcp_request *req)
10491051
{
10501052
struct nvme_tcp_queue *queue = req->queue;
1053+
size_t offset = req->offset;
10511054
int ret;
10521055
struct msghdr msg = { .msg_flags = MSG_DONTWAIT };
10531056
struct kvec iov = {
1054-
.iov_base = &req->ddgst + req->offset,
1057+
.iov_base = (u8 *)&req->ddgst + req->offset,
10551058
.iov_len = NVME_TCP_DIGEST_LENGTH - req->offset
10561059
};
10571060

@@ -1064,7 +1067,7 @@ static int nvme_tcp_try_send_ddgst(struct nvme_tcp_request *req)
10641067
if (unlikely(ret <= 0))
10651068
return ret;
10661069

1067-
if (req->offset + ret == NVME_TCP_DIGEST_LENGTH) {
1070+
if (offset + ret == NVME_TCP_DIGEST_LENGTH) {
10681071
nvme_tcp_done_send_req(queue);
10691072
return 1;
10701073
}

drivers/nvme/target/tcp.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -702,7 +702,7 @@ static int nvmet_try_send_ddgst(struct nvmet_tcp_cmd *cmd, bool last_in_batch)
702702
struct nvmet_tcp_queue *queue = cmd->queue;
703703
struct msghdr msg = { .msg_flags = MSG_DONTWAIT };
704704
struct kvec iov = {
705-
.iov_base = &cmd->exp_ddgst + cmd->offset,
705+
.iov_base = (u8 *)&cmd->exp_ddgst + cmd->offset,
706706
.iov_len = NVME_TCP_DIGEST_LENGTH - cmd->offset
707707
};
708708
int ret;
@@ -1096,7 +1096,7 @@ static int nvmet_tcp_try_recv_pdu(struct nvmet_tcp_queue *queue)
10961096
}
10971097

10981098
if (queue->hdr_digest &&
1099-
nvmet_tcp_verify_hdgst(queue, &queue->pdu, queue->offset)) {
1099+
nvmet_tcp_verify_hdgst(queue, &queue->pdu, hdr->hlen)) {
11001100
nvmet_tcp_fatal_error(queue); /* fatal */
11011101
return -EPROTO;
11021102
}
@@ -1428,6 +1428,7 @@ static void nvmet_tcp_uninit_data_in_cmds(struct nvmet_tcp_queue *queue)
14281428

14291429
static void nvmet_tcp_release_queue_work(struct work_struct *w)
14301430
{
1431+
struct page *page;
14311432
struct nvmet_tcp_queue *queue =
14321433
container_of(w, struct nvmet_tcp_queue, release_work);
14331434

@@ -1447,6 +1448,8 @@ static void nvmet_tcp_release_queue_work(struct work_struct *w)
14471448
nvmet_tcp_free_crypto(queue);
14481449
ida_simple_remove(&nvmet_tcp_queue_ida, queue->idx);
14491450

1451+
page = virt_to_head_page(queue->pf_cache.va);
1452+
__page_frag_cache_drain(page, queue->pf_cache.pagecnt_bias);
14501453
kfree(queue);
14511454
}
14521455

0 commit comments

Comments
 (0)