diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c index 8cb15ee5b249..9d71275fff9e 100644 --- a/drivers/nvme/host/tcp.c +++ b/drivers/nvme/host/tcp.c @@ -1217,6 +1217,7 @@ static int nvme_tcp_alloc_async_req(struct nvme_tcp_ctrl *ctrl) static void nvme_tcp_free_queue(struct nvme_ctrl *nctrl, int qid) { + struct page *page; struct nvme_tcp_ctrl *ctrl = to_tcp_ctrl(nctrl); struct nvme_tcp_queue *queue = &ctrl->queues[qid]; @@ -1226,6 +1227,9 @@ static void nvme_tcp_free_queue(struct nvme_ctrl *nctrl, int qid) if (queue->hdr_digest || queue->data_digest) nvme_tcp_free_crypto(queue); + page = virt_to_head_page(queue->pf_cache.va); + __page_frag_cache_drain(page, queue->pf_cache.pagecnt_bias); + queue->pf_cache.va = NULL; sock_release(queue->sock); kfree(queue->pdu); mutex_destroy(&queue->queue_lock); @@ -1594,6 +1598,7 @@ static struct blk_mq_tag_set *nvme_tcp_alloc_tagset(struct nvme_ctrl *nctrl, struct nvme_tcp_ctrl *ctrl = to_tcp_ctrl(nctrl); struct blk_mq_tag_set *set; int ret; + static int fail = 0; if (admin) { set = &ctrl->admin_tag_set; @@ -1622,6 +1627,11 @@ static struct blk_mq_tag_set *nvme_tcp_alloc_tagset(struct nvme_ctrl *nctrl, set->nr_maps = nctrl->opts->nr_poll_queues ? HCTX_MAX_TYPES : 2; } + if (fail++ == 5) { + fail = 0; + return ERR_PTR(-ENOMEM); + } + ret = blk_mq_alloc_tag_set(set); if (ret) return ERR_PTR(ret);