From patchwork Mon Nov 8 11:49:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xuan Zhuo X-Patchwork-Id: 12608313 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id AEB28C433EF for ; Mon, 8 Nov 2021 11:49:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 958D061288 for ; Mon, 8 Nov 2021 11:49:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239335AbhKHLwk (ORCPT ); Mon, 8 Nov 2021 06:52:40 -0500 Received: from out30-42.freemail.mail.aliyun.com ([115.124.30.42]:37818 "EHLO out30-42.freemail.mail.aliyun.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239330AbhKHLwi (ORCPT ); Mon, 8 Nov 2021 06:52:38 -0500 X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R121e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=e01e04407;MF=xuanzhuo@linux.alibaba.com;NM=1;PH=DS;RN=6;SR=0;TI=SMTPD_---0Uvb-rcW_1636372192; Received: from localhost(mailfrom:xuanzhuo@linux.alibaba.com fp:SMTPD_---0Uvb-rcW_1636372192) by smtp.aliyun-inc.com(127.0.0.1); Mon, 08 Nov 2021 19:49:52 +0800 From: Xuan Zhuo To: virtualization@lists.linux-foundation.org, netdev@vger.kernel.org Cc: "Michael S. Tsirkin" , Jason Wang , "David S. Miller" , Jakub Kicinski Subject: [PATCH v4 2/3] virtio: cache indirect desc for packed Date: Mon, 8 Nov 2021 19:49:50 +0800 Message-Id: <20211108114951.92862-3-xuanzhuo@linux.alibaba.com> X-Mailer: git-send-email 2.31.0 In-Reply-To: <20211108114951.92862-1-xuanzhuo@linux.alibaba.com> References: <20211108114951.92862-1-xuanzhuo@linux.alibaba.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org In the case of using indirect, indirect desc must be allocated and released each time, which increases a lot of cpu overhead. Here, a cache is added for indirect. If the number of indirect desc to be applied for is less than desc_cache_thr, the desc array with the size of desc_cache_thr is fixed and cached for reuse. Signed-off-by: Xuan Zhuo --- drivers/virtio/virtio_ring.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index a4a91c497a83..76a974219ffd 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c @@ -1092,7 +1092,11 @@ static void vring_unmap_desc_packed(const struct vring_virtqueue *vq, } } -static struct vring_packed_desc *alloc_indirect_packed(unsigned int total_sg, +#define desc_cache_get_packed(vq, n, gfp) \ + _desc_cache_get(vq, n, gfp, struct vring_packed_desc) + +static struct vring_packed_desc *alloc_indirect_packed(struct vring_virtqueue *vq, + unsigned int total_sg, gfp_t gfp) { struct vring_packed_desc *desc; @@ -1104,7 +1108,7 @@ static struct vring_packed_desc *alloc_indirect_packed(unsigned int total_sg, */ gfp &= ~__GFP_HIGHMEM; - desc = kmalloc_array(total_sg, sizeof(struct vring_packed_desc), gfp); + desc = desc_cache_get_packed(vq, total_sg, gfp); return desc; } @@ -1124,7 +1128,7 @@ static int virtqueue_add_indirect_packed(struct vring_virtqueue *vq, dma_addr_t addr; head = vq->packed.next_avail_idx; - desc = alloc_indirect_packed(total_sg, gfp); + desc = alloc_indirect_packed(vq, total_sg, gfp); if (unlikely(vq->vq.num_free < 1)) { pr_debug("Can't add buf len 1 - avail = 0\n"); @@ -1215,7 +1219,7 @@ static int virtqueue_add_indirect_packed(struct vring_virtqueue *vq, for (i = 0; i < err_idx; i++) vring_unmap_desc_packed(vq, &desc[i]); - kfree(desc); + desc_cache_put(vq, desc, total_sg); END_USE(vq); return -ENOMEM; @@ -1440,20 +1444,22 @@ static void detach_buf_packed(struct vring_virtqueue *vq, } if (vq->indirect) { - u32 len; + u32 len, n; /* Free the indirect table, if any, now that it's unmapped. */ desc = state->indir_desc; if (!desc) return; + len = vq->packed.desc_extra[id].len; + n = len / sizeof(struct vring_packed_desc); + if (vq->use_dma_api) { - len = vq->packed.desc_extra[id].len; - for (i = 0; i < len / sizeof(struct vring_packed_desc); - i++) + for (i = 0; i < n; i++) vring_unmap_desc_packed(vq, &desc[i]); } - kfree(desc); + + desc_cache_put(vq, desc, n); state->indir_desc = NULL; } else if (ctx) { *ctx = state->indir_desc; @@ -1772,6 +1778,8 @@ static struct virtqueue *vring_create_virtqueue_packed( !context; vq->event = virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX); + desc_cache_init(vq); + if (virtio_has_feature(vdev, VIRTIO_F_ORDER_PLATFORM)) vq->weak_barriers = false; @@ -2391,8 +2399,8 @@ void vring_del_virtqueue(struct virtqueue *_vq) if (!vq->packed_ring) { kfree(vq->split.desc_state); kfree(vq->split.desc_extra); - desc_cache_free(vq); } + desc_cache_free(vq); kfree(vq); } EXPORT_SYMBOL_GPL(vring_del_virtqueue);