From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail.openvz.org (unknown [69.168.225.77]) by lore.virtuozzo.com (Postfix) with ESMTPS id E607380478 for ; Wed, 30 Sep 2026 07:36:19 +0000 (UTC) Received: from mail.openvz.org (localhost [127.0.0.1]) by mail.openvz.org (8.14.4/8.14.4) with ESMTP id 68U7Z4MQ014564; Wed, 30 Sep 2026 10:35:05 +0300 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.openvz.org 68U7Z4MQ014564 Authentication-Results: mail.openvz.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=virtuozzo.com header.i=@virtuozzo.com header.b="u7sJIQCy" Received: from mail-wr1-f69.google.com (mail-wr1-f69.google.com [209.85.221.69]) by mail.openvz.org (8.14.4/8.14.4) with ESMTP id 68U7Z3Pb014552 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=FAIL) for ; Wed, 30 Sep 2026 10:35:03 +0300 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.openvz.org 68U7Z3Pb014552 Received: by mail-wr1-f69.google.com with SMTP id ffacd0b85a97d-48afcecb035so221886f8f.0 for ; Wed, 30 Sep 2026 00:35:03 -0700 (PDT) X-Gm-Message-State: AFq9FYJ5mZHhrpWGfKH3uhiV44BKTlnKVHZ+t9DF1LKBjAZXiVZT0zRR c6pRJ4g0HbSBFUxr3qAQTvFAxB8HaYJmD2g0XAFfHkvXi74byIMVzPmxHUp6phvM/etu6qn6CYN e9khSlPUArh+lfRxfeqGgxprtBghLZ7Q/+qkDSNNRidXWZumeQCu+DA== X-Gm-Gg: AYBFou16iTpnfEbROHm5gpSoN9aZBltPSlb6G6jXHtbsDtDaziAdHwV2nkLSZ/Jqg7u qmsMGGVgxx/opKgwcSwLpT1OyejgMO0/SY4hz1BYNcAdsEQ6m1PQLShmP8hTogxKTYP/u1tfkhI Ws8Jd/k7MnqusLaXcloXcbrA3OcGSxGRFQYx3xjsXXRs3cyJ7kHf5KpjzXQ/VXh1mvG4A//h0Ji kpMSjlkbrthzfKlGvQSo+lbW+D8He5l4Sb7rzERTHCa2N6fb+rcHWqZI85ki4g70dnubGCmmcX2 ghtMx8C3xIiVjdEyRTRuWeY8Wv82LQ5qpJn56TdUY6vUZPS2psa9HekMJZ2+6mq8jIIA1zQK2C3 H7nsHFS/Eqz4hiT8= X-Received: by 2002:a05:6000:2389:b0:487:342:eb28 with SMTP id ffacd0b85a97d-48b0250e93bmr1235682f8f.24.1790753702955; Wed, 30 Sep 2026 00:35:02 -0700 (PDT) X-Received: by 2002:a05:6000:2389:b0:487:342:eb28 with SMTP id ffacd0b85a97d-48b0250e93bmr1235596f8f.24.1790753702271; Wed, 30 Sep 2026 00:35:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1790753702; cv=none; d=google.com; s=arc-20260327; b=VjBhTHYxerLqZq7zmPC0SbO1g1occPBt07vVouV5b5GrT+B5slnjBrUJ2lYM1beJfY y92CNwQ+jLIqBqGiDTG+bMDzxAKAqBMvKMV7AfZhv3qD1Kf7DD/r2752JMglUYUNp4y8 TDzEJRm4S2pHHDkFZg8TTq4LXTiMwk/yko2fv7JAkNNQrfAV3YrUtb7JC0Li9lCkEq4r CVJW3Sh4j60AOeMDHjo99GpoLsB9Ro/sptdbmGjxB/yOyBH4fAw0qvhsjz0kIHqsWDte ZDysPRCfWbEL2GXzRsy1KmPuAbuaVs6L21Ojryg3XQ1D66C/FzMe8Fcbx1P/7NATli7G 740g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20260327; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:dkim-signature; bh=E5/zyPD8Z94R2mb44KAy/A2hAyYSEO8dFSdFQVcVjTI=; fh=6JpqpGxFeFNaDh+k4t2UfZyo3rKe/54dyQ52T8vVmSc=; b=ole1iUT2bfPrCBlRKC2iZ8wQ1BwWUx0TZ/hEL3IxoL0vVSImN6FI5v5LPAwSiGaV2w BX12QxtAkjq6t09EtQR22uz9CxV8SGzihkL2b3BJ2mNJJEdhZcnwFnzkY54uB734Cxju TnpckvG5w9SBHopuMvrp8BrHonf/Y1KLNDrYqnJsAAW+X5T79dJqDMt1Ld/vimH/LISs tF3lKFbPurtW5NsCzuheMwBI1/Xl7l+l7Fzvp9SfDBdAsImOcGakwlQJBdqv4D7ReIM/ ztFL7CWOWfxRM8xs/jrXTHKSTeCfknU1Vyk71lKNTIDFaWIaUb/MalBOiEfOnnM9bCme H5Xw==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@virtuozzo.com header.s=relay header.b=u7sJIQCy; spf=pass (google.com: domain of kui.liu@virtuozzo.com designates 130.117.225.111 as permitted sender) smtp.mailfrom=kui.liu@virtuozzo.com; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=virtuozzo.com Received: from relay.virtuozzo.com (relay.virtuozzo.com. [130.117.225.111]) by mx.google.com with ESMTPS id ffacd0b85a97d-48b029f067bsi972956f8f.304.2026.09.30.00.35.02 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 30 Sep 2026 00:35:02 -0700 (PDT) Received-SPF: pass (google.com: domain of kui.liu@virtuozzo.com designates 130.117.225.111 as permitted sender) client-ip=130.117.225.111; Authentication-Results: mx.google.com; dkim=pass header.i=@virtuozzo.com header.s=relay header.b=u7sJIQCy; spf=pass (google.com: domain of kui.liu@virtuozzo.com designates 130.117.225.111 as permitted sender) smtp.mailfrom=kui.liu@virtuozzo.com; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=virtuozzo.com DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=virtuozzo.com; s=relay; h=Message-Id:Content-Type:MIME-Version:Subject:Date :From; bh=E5/zyPD8Z94R2mb44KAy/A2hAyYSEO8dFSdFQVcVjTI=; b=u7sJIQCyP7dSbzInaw5 sOrH9WyXI7GX+vVNqLcOhxtJpdbiZDEtbCAghcgMa5DLrRocTH03v861eBKNvOzvKqVn2vRHphe2u EscszMBbKkHpKDpZji9KjMc6Mv6cqhPAii6xXKfDWvOZE9Z5roj1rBxAL6EZFc2DULr/OnTCQQ+o6 AuY3RPpvPVyTht45f8lOEOD5ocqj5B8677yzilNQxfSsVF8iCPkCkACkgmH8lPwzYslDR8gZxMNdJ wj8F5g9BUBUCY6c+Egk2w7CRi9CEEPZoxcuzxIxJsBw8qcUXClAa1RKn8pB7hZeZAXSGw0FhzrNgX TROXgkwELuLbbJA==; Received: from ch-vpn.virtuozzo.com ([130.117.225.6] helo=LK-MBP.local) by relay.virtuozzo.com with esmtp (Exim 4.96) (envelope-from ) id 1xBon8-00FyU7-0J; Wed, 30 Sep 2026 09:35:01 +0200 From: Liu Kui Date: Wed, 30 Sep 2026 15:34:32 +0800 MIME-Version: 1.0 Message-Id: <20260930-sockio-refactor-8-1-v1-2-806348b9eb26@virtuozzo.com> References: <20260930-sockio-refactor-8-1-v1-0-806348b9eb26@virtuozzo.com> In-Reply-To: <20260930-sockio-refactor-8-1-v1-0-806348b9eb26@virtuozzo.com> To: Konstantin Khorenko X-Mailer: b4 0.16.0 X-OZ-Fwd: true Cc: azaitsev@virtuozzo.com, devel@openvz.org, Liu Kui Subject: [Devel] [PATCH hci-8.1 2/3] fs/fuse kio: refactor transmit path in pcs_sockio_send() X-BeenThere: devel@openvz.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: OpenVZ development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: devel-bounces@openvz.org Errors-To: devel-bounces@openvz.org The transmit path sends one iov_iter segment per sock_sendmsg() call, and the bvec builder produces one bio_vec per 4k page, so a 1M data chunk costs up to 256 sendmsg calls where the socket could take the whole iov_iter at once. Replace do_send_one_seg() with do_sockio_sendmsg(), which submits the entire iov_iter in a single sock_sendmsg() call (with MSG_SPLICE_PAGES when all pages qualify), reducing pcs_sockio_send() to pure queue management. Also clear PCS_MSG_BUSY in the transport whenever IO on the msg ends, like the rdma transport does, instead of relying on krpc to mop it up. https://virtuozzo.atlassian.net/browse/VSTOR-142167 Signed-off-by: Liu Kui --- fs/fuse/kio/pcs/pcs_sock_io.c | 207 ++++++++++++++++++++++-------------------- 1 file changed, 109 insertions(+), 98 deletions(-) diff --git a/fs/fuse/kio/pcs/pcs_sock_io.c b/fs/fuse/kio/pcs/pcs_sock_io.c index fa26105b2185..828c8a98cabf 100644 --- a/fs/fuse/kio/pcs/pcs_sock_io.c +++ b/fs/fuse/kio/pcs/pcs_sock_io.c @@ -139,54 +139,6 @@ static bool pcs_should_fail_sock_io(void) } #endif -static int do_send_one_seg(struct socket *sock, struct iov_iter *it, size_t left, int has_more) -{ - int ret = -EIO; - size_t size = iov_iter_single_seg_count(it); - bool more = (size < left); - int flags = (MSG_DONTWAIT | MSG_NOSIGNAL) | ((more || has_more) ? MSG_MORE : 0); - struct msghdr msg = { .msg_flags = flags }; - - if (unlikely(pcs_use_eor) && !more) - flags |= MSG_EOR; - - DTRACE("sock(%px) len:%ld, more:%d\n", sock, iov_iter_count(it), more); - - if (unlikely(!size)) - return 0; - - if (pcs_should_fail_sock_io()) - goto out; - - if (iov_iter_is_kvec(it)) { - struct kvec kv; - - iov_iter_get_kvec(it, &kv); - BUG_ON(kv.iov_len != size); - - iov_iter_kvec(&msg.msg_iter, ITER_SOURCE, &kv, 1, size); - } else if (iov_iter_is_bvec(it)) { - struct bio_vec bv; - - /* iov_iter_iovec() for ITER_BVEC */ - bvec_set_page(&bv, it->bvec->bv_page, - min(size, it->bvec->bv_len - it->iov_offset), - it->bvec->bv_offset + it->iov_offset); - - if (sendpage_ok(bv.bv_page)) - msg.msg_flags |= MSG_SPLICE_PAGES; - else - msg.msg_flags &= ~MSG_SPLICE_PAGES; - - iov_iter_bvec(&msg.msg_iter, ITER_SOURCE, &bv, 1, bv.bv_len); - } - - ret = sock_sendmsg(sock, &msg); -out: - DTRACE("sock(%px) len:%ld, more:%d ret:%d\n", sock, iov_iter_count(it), more, ret); - return ret; -} - static int do_sock_recv(struct socket *sock, void *buf, size_t len) { @@ -352,14 +304,110 @@ static void pcs_sockio_recv(struct pcs_sockio *sio) } +static bool iov_iter_sendpages_ok(struct iov_iter *it) +{ + const struct bio_vec *bvec = it->bvec; + + if (!iov_iter_is_bvec(it)) + return false; + + while (bvec < (it->bvec + it->nr_segs)) { + if (!sendpages_ok(bvec->bv_page, bvec->bv_len, bvec->bv_offset)) + return false; + bvec++; + } + + return true; +} + +static int do_sockio_sendmsg(struct pcs_sockio *sio, struct pcs_msg *msg) +{ + struct iov_iter *it = &sio->write_iter; + unsigned int flags = MSG_DONTWAIT | MSG_NOSIGNAL; + + if (unlikely(pcs_should_fail_sock_io())) + return -PCS_ERR_NET_ABORT; + + set_bit(PCS_MSG_BUSY, &msg->flags); + + /* pair with the smp_mb() between set PCS_MSG_ABORTED and test PCS_MSG_BUSY */ + smp_mb(); + /* Shouldn't abort a half sent message */ + if (unlikely(test_bit(PCS_MSG_ABORTED, &msg->flags)) && !sio->write_offset) { + pcs_set_local_error(&msg->error, PCS_ERR_CANCEL_REQUEST); + goto out; + } + + while (sio->write_offset < msg->size) { + size_t left = msg->size - sio->write_offset; + struct msghdr sockmsg = {.msg_flags = flags}; + + TRACE("sio(%px) offset:%d msg:%px left:%zu, it->len:%zu\n", sio, sio->write_offset, msg, left, iov_iter_count(it)); + + if (!iov_iter_count(it)) { + /* Current iter is exhausted, init new one */ + msg->get_iter(msg, sio->write_offset, it, WRITE); + } + + BUG_ON(iov_iter_count(it) > left); + + if (iov_iter_count(it) < left || + msg->list.next != &sio->write_queue) + sockmsg.msg_flags |= MSG_MORE; + if (iov_iter_count(it) == left && unlikely(pcs_use_eor)) + sockmsg.msg_flags |= MSG_EOR; + + if (iov_iter_sendpages_ok(it)) + sockmsg.msg_flags |= MSG_SPLICE_PAGES; + + sockmsg.msg_iter = *it; + + while (iov_iter_count(it)) { + int ret; + + DTRACE("sock(%px) len:%zu, flags:%08x\n", sio->socket, iov_iter_count(it), sockmsg.msg_flags); + ret = sock_sendmsg(sio->socket, &sockmsg); + DTRACE("sock(%px) len:%zu, flags:%08x, ret=%d\n", sio->socket, iov_iter_count(it), sockmsg.msg_flags, ret); + if (ret <= 0) { + if (ret == -EAGAIN) { + if (!time_is_before_jiffies((unsigned long)(msg->start_time + sio->send_timeout))) + /* Keep PCS_MSG_BUSY: the msg is half + * sent and the transfer will resume, + * it must not be aborted meanwhile. */ + return 0; + + ret = -PCS_ERR_WRITE_TIMEOUT; + } else { + WARN_ON(ret == 0); + ret = -PCS_ERR_NET_ABORT; + } + + /* The caller aborts the connection: no more IO on + * this msg, release it for pcs_msg_abort() before + * sio_abort() completes it. */ + clear_and_wake_up_bit(PCS_MSG_BUSY, &msg->flags); + return ret; + } + + iov_iter_advance(it, ret); + sio->write_offset += ret; + } + WARN_ON(msg_data_left(&sockmsg)); + } + +out: + clear_and_wake_up_bit(PCS_MSG_BUSY, &msg->flags); + return 1; +} + static void pcs_sockio_send(struct pcs_sockio *sio) { struct pcs_rpc *ep __maybe_unused = sio->netio.parent; - struct iov_iter *it = &sio->write_iter; unsigned long loop_timeout = jiffies + PCS_SIO_SLICE; struct pcs_msg * msg; - int done = 0; int count = 0; + int ret = 0; + bool to_push = false; while (!list_empty(&sio->write_queue)) { msg = list_first_entry(&sio->write_queue, struct pcs_msg, list); @@ -380,54 +428,15 @@ static void pcs_sockio_send(struct pcs_sockio *sio) return; } - set_bit(PCS_MSG_BUSY, &msg->flags); - - /* pair with the smp_mb() between set PCS_MSG_ABORTED and test PCS_MSG_BUSY */ - smp_mb(); - - /* Shouldn't abort a half sent message */ - if (unlikely(test_bit(PCS_MSG_ABORTED, &msg->flags)) && !sio->write_offset) { - pcs_set_local_error(&msg->error, PCS_ERR_CANCEL_REQUEST); - goto skip_send; - } - - /* TODO: cond resched here? */ - while (sio->write_offset < msg->size) { - size_t left = msg->size - sio->write_offset; - int has_more = (msg->list.next != &sio->write_queue); - int n; - - TRACE(PEER_FMT "offset:%d msg:%px left:%ld, it->len:%ld\n", PEER_ARGS(ep), sio->write_offset, msg, - left, iov_iter_count(it)); - - if (!iov_iter_count(it)) { - /* Current iter is exhausted, init new one */ - msg->get_iter(msg, sio->write_offset, it, WRITE); - } - BUG_ON(iov_iter_count(it) > left); - n = do_send_one_seg(sio->socket, it, left, has_more); - if (n > 0) { - sio->write_offset += n; - iov_iter_advance(it, n); - done = 1; - } else { - if (n == 0) - WARN_ON(1); - - if (n == -EAGAIN) { - unsigned long timeout = msg->start_time + sio->send_timeout; - if (time_is_before_jiffies(timeout)) - sio_abort(sio, PCS_ERR_WRITE_TIMEOUT); - return; - } - sio_abort(sio, PCS_ERR_NET_ABORT); - return; - } + /* Send out this msg */ + ret = do_sockio_sendmsg(sio, msg); + if (ret <= 0) { + if (ret < 0) + sio_abort(sio, -ret); + return; } -skip_send: - clear_and_wake_up_bit(PCS_MSG_BUSY, &msg->flags); - + to_push = true; list_del_init(&msg->list); sio->write_queue_len -= msg->size; @@ -435,8 +444,9 @@ static void pcs_sockio_send(struct pcs_sockio *sio) if (sio->write_wakeup) sio->write_wakeup(sio); } + sio->write_offset = 0; - iov_iter_kvec(it, WRITE, NULL, 0, 0); + iov_iter_kvec(&sio->write_iter, WRITE, NULL, 0, 0); pcs_msg_sent(msg); msg->done(msg); if (++count >= PCS_SIO_PREEMPT_LIMIT || @@ -445,7 +455,8 @@ static void pcs_sockio_send(struct pcs_sockio *sio) break; } } - if (done) + + if (to_push) sio_push(sio); } -- Git-155) _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel