Received: by 2002:a05:6a10:9848:0:0:0:0 with SMTP id x8csp550491pxf; Thu, 18 Mar 2021 06:56:44 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyrqz0hVUT19rHbRw8O0BqkVRrc2zuFIl3Zr1vdZj4diXGPhT8JNy887PqQXYvkGjoxCTMa X-Received: by 2002:a05:6402:32d:: with SMTP id q13mr3834681edw.17.1616075803879; Thu, 18 Mar 2021 06:56:43 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1616075803; cv=none; d=google.com; s=arc-20160816; b=xm+NrnuHcHlp6GzAEFgT+4Fkoo9vJax0ssNEIVVZMXXVEZL7mfBikpaBaWDwJWz/G+ 1KmtJG5McJDm7MOH03DhCEhnVUteELh+OKUQFxMsJ/9aYmI9aIgwAeXol8r4cSdRXyKz /cxzUXHlfXij1evtpC1WjTpLfJ/L1f3nOvnMmoPQ76O5Jz0AsM9LSk0BE9Wt5CksdT8l PzWdUeuzoDGToG0ZrVMWymc4OqrMEEEzn/kLPW7NqY1HizSHWtxVlrXMa5TfT37B6r6O 5Ml/vTG2LKIStFG8Q6AStuVejWgkaHaX4GpdV+jbk2b+yAXWhfBMfRG7KDE2OPmU4YEr diYg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=qopB9y1x5EWojgQ3TD0iEI7yb51KrfAHtn13P+oXggA=; b=K1HcNFaczcDMZ0al464PUNiWS2Nku71q3dS7qjWo14fvSlcJl8agILXTjkKUr/nM8I xIblv1hDRYaimv+WeVnwvMOfFxr5bz8BHa7Rtl41CpZAVAimaLfiKIVu9frYu8vyUmPp 3PrSdFBiYTC8/NpVvaMUvHsZEBJC6v7q3kyNiK4fxGiP1eO4tGRXVhRxYq0LWJLSUFVO Uj1ZWgkKkXfg7yzh2fAbiGVBq2a/Lm/t1z5cD0j/h3q+MaUryNkqO/dhJj50eqw6Iwl4 +ITggT5tZeHi0BgIEnYq0RIeE60tZFTKuaLReo6bgwzDiFdDDLvuSKa+ndfO/LADhZhZ xm3w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=J+X3DdZf; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id z12si1589610ejj.612.2021.03.18.06.56.21; Thu, 18 Mar 2021 06:56:43 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=J+X3DdZf; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231466AbhCRNws (ORCPT + 99 others); Thu, 18 Mar 2021 09:52:48 -0400 Received: from us-smtp-delivery-124.mimecast.com ([63.128.21.124]:28999 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231357AbhCRNw3 (ORCPT ); Thu, 18 Mar 2021 09:52:29 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1616075548; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=qopB9y1x5EWojgQ3TD0iEI7yb51KrfAHtn13P+oXggA=; b=J+X3DdZfssF7tuw1aMKhRndld676/QibpKSahNrDJnKz4rzrnxZlQaDPrOnWhTrTmMhXyZ rRXdw7rkeTtNk48ya9f8OB4wVjV5qs0vNFWbwuB2veof2ioVJgrkTHR86vwsV2n/SQ4ot3 xbk1RchPSEr0fp/tB8ZWmLRKgxP/L7k= Received: from mail-ot1-f71.google.com (mail-ot1-f71.google.com [209.85.210.71]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-602-ajhgTWmJMjOo9xqQFCf3LA-1; Thu, 18 Mar 2021 09:52:27 -0400 X-MC-Unique: ajhgTWmJMjOo9xqQFCf3LA-1 Received: by mail-ot1-f71.google.com with SMTP id v24so3812111ota.0 for ; Thu, 18 Mar 2021 06:52:27 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=qopB9y1x5EWojgQ3TD0iEI7yb51KrfAHtn13P+oXggA=; b=GTjxOPCN8Ws79sglTbU0yHp+KWjfqov10rJx+cjE+3zsMoyO17MI6P14gRuq/qUB89 37b5UNWJhkwo/9r7mDbt0zqvTnp+ey79T9DdD/bNWf1nZmQLb9+ubT7Xmpn486dOB+fg 9ht9TFjk2bG1GbIFseXfIJj8duHCTrAl0moen/0PzeftgAUAv/0V6mGIrzaFH2hZc28J FxHQOmRTm0ZDgYOzX7tmA3ssdEuTglGncq3X0lSAsJIPbyeXChlG3s5ugnbQJMkaaoN6 S8KzzYkRacuv18GaUYLbO2HnfHSZmCwOVwWjJZMCftlcKVe+IyvIQRbkrRGZ+cMpofyZ 8jDQ== X-Gm-Message-State: AOAM5303Qye4goZXBJ8ThxkT4tKGqRui66mKNebLGutnYbcr0q0HOl53 tBuYBfgNUYMdCaHbNCt6jAZYPsnP2Mk/HG6TOjTWhQdUISy+Rak/ZUwLAMIhoxOl+3dkwnKY2lo vPexvb5KeZi9uhBSnGin0rugo X-Received: by 2002:aca:f13:: with SMTP id 19mr3149428oip.56.1616075546702; Thu, 18 Mar 2021 06:52:26 -0700 (PDT) X-Received: by 2002:aca:f13:: with SMTP id 19mr3149414oip.56.1616075546551; Thu, 18 Mar 2021 06:52:26 -0700 (PDT) Received: from redhat.redhat.com (ip68-103-222-6.ks.ok.cox.net. [68.103.222.6]) by smtp.gmail.com with ESMTPSA id i11sm465342otp.76.2021.03.18.06.52.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 18 Mar 2021 06:52:26 -0700 (PDT) From: Connor Kuehl To: virtio-fs@redhat.com Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, virtualization@lists.linux-foundation.org, stefanha@redhat.com, vgoyal@redhat.com, miklos@szeredi.hu, jasowang@redhat.com, mst@redhat.com Subject: [PATCH 2/3] virtiofs: split requests that exceed virtqueue size Date: Thu, 18 Mar 2021 08:52:22 -0500 Message-Id: <20210318135223.1342795-3-ckuehl@redhat.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210318135223.1342795-1-ckuehl@redhat.com> References: <20210318135223.1342795-1-ckuehl@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org If an incoming FUSE request can't fit on the virtqueue, the request is placed onto a workqueue so a worker can try to resubmit it later where there will (hopefully) be space for it next time. This is fine for requests that aren't larger than a virtqueue's maximum capacity. However, if a request's size exceeds the maximum capacity of the virtqueue (even if the virtqueue is empty), it will be doomed to a life of being placed on the workqueue, removed, discovered it won't fit, and placed on the workqueue yet again. Furthermore, from section 2.6.5.3.1 (Driver Requirements: Indirect Descriptors) of the virtio spec: "A driver MUST NOT create a descriptor chain longer than the Queue Size of the device." To fix this, limit the number of pages FUSE will use for an overall request. This way, each request can realistically fit on the virtqueue when it is decomposed into a scattergather list and avoid violating section 2.6.5.3.1 of the virtio spec. Signed-off-by: Connor Kuehl --- fs/fuse/fuse_i.h | 5 +++++ fs/fuse/inode.c | 7 +++++++ fs/fuse/virtio_fs.c | 14 ++++++++++++++ 3 files changed, 26 insertions(+) diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 68cca8d4db6e..f0e4ee906464 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -555,6 +555,11 @@ struct fuse_conn { /** Maxmum number of pages that can be used in a single request */ unsigned int max_pages; +#if IS_ENABLED(CONFIG_VIRTIO_FS) + /** Constrain ->max_pages to this value during feature negotiation */ + unsigned int transport_capacity; +#endif + /** Input queue */ struct fuse_iqueue iq; diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index b0e18b470e91..42cc72ba13d9 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -1058,6 +1058,13 @@ static void process_init_reply(struct fuse_mount *fm, struct fuse_args *args, fc->no_flock = 1; } +#if IS_ENABLED(CONFIG_VIRTIO_FS) + /* fuse_conn_init() sets this to zero for all others, this is + * explicitly set by virtio_fs. + */ + if (fc->transport_capacity) + fc->max_pages = min_t(unsigned int, fc->max_pages, fc->transport_capacity); +#endif fm->sb->s_bdi->ra_pages = min(fm->sb->s_bdi->ra_pages, ra_pages); fc->minor = arg->minor; diff --git a/fs/fuse/virtio_fs.c b/fs/fuse/virtio_fs.c index 8868ac31a3c0..a6ffba85d59a 100644 --- a/fs/fuse/virtio_fs.c +++ b/fs/fuse/virtio_fs.c @@ -18,6 +18,12 @@ #include #include "fuse_i.h" +/* Used to help calculate the FUSE connection's max_pages limit for a request's + * size. Parts of the struct fuse_req are sliced into scattergather lists in + * addition to the pages used, so this can help account for that overhead. + */ +#define FUSE_HEADER_OVERHEAD 4 + /* List of virtio-fs device instances and a lock for the list. Also provides * mutual exclusion in device removal and mounting path */ @@ -1408,6 +1414,7 @@ static int virtio_fs_get_tree(struct fs_context *fsc) struct super_block *sb; struct fuse_conn *fc; struct fuse_mount *fm; + unsigned int virtqueue_size; int err; /* This gets a reference on virtio_fs object. This ptr gets installed @@ -1435,6 +1442,13 @@ static int virtio_fs_get_tree(struct fs_context *fsc) fc->delete_stale = true; fc->auto_submounts = true; + /* Tell FUSE to split requests that exceed the virtqueue's size */ + virtqueue_size = virtqueue_get_vring_size(fs->vqs[VQ_REQUEST].vq); + WARN_ON(virtqueue_size <= FUSE_HEADER_OVERHEAD); + fc->transport_capacity = min_t(unsigned int, + virtqueue_size - FUSE_HEADER_OVERHEAD, + FUSE_MAX_MAX_PAGES); + fsc->s_fs_info = fm; sb = sget_fc(fsc, virtio_fs_test_super, set_anon_super_fc); if (fsc->s_fs_info) { -- 2.30.2