From nobody Mon Apr 08 20:29:45 2024 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4VD10n6bVYz5HjPq; Mon, 8 Apr 2024 20:29:45 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4VD10n3dwMz4602; Mon, 8 Apr 2024 20:29:45 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1712608185; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=FnxIbTY7ZAI8aFN3M4WSzO7ErldGp7JIm94hjjxe6I0=; b=j/apGFezr9VJXf7Mv9P0Ap5mo1L4/SnkvIpneu8TY90Byry3JBtgFyG2CKOKXS+sJrQ/lt 9pq3okGwihjeegS/cTnJZG9Lwxgi64ywKKE8AmqipJQzzAmAdFPhA/w/LViITB8uOM3QCq KCFRSfg3S3+2aApFGHvCMlf4vs0lfcKW4uA1fxHfdrGTeZ7FJHy7ZdLfBXXR2J49cFGzyX A3cUipBe4uAhvmlp+1DMEOETyIsbqxH2N6d2OYj2QbUO48dXwEX3o/AIRS5u2Gvc4VsS15 v4GqDjHcktA7DT8jfjqrLFqlpwV2p1U0neXZ4xIb0JtYrTJIGvcfE5AJMdz/qw== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1712608185; a=rsa-sha256; cv=none; b=ENn3kc9lt/chHY1d1mwWLb9FauFiHVUcvSJvP0kAdEQ7sN6RqKj5IuTEhnwk8Bp83Jxi+y MAfPsIiN0KoDuVzdmQfDLz6elYyOlnqoOrVL1cJ4TSfJ2sxhcb6nxUjdWcH5X58Lm2dkYm A4UllvniMaGHPVD1kq4HSJB/+Ek3ziE8LZQHb41ychJqMkNI/CaO4PPc6f5uXRfR5Ik57G Ai053KY7fTUA0vxBCJUIbhWTRybwk7l5AU6BPZklLuWfGJag6jd2TrRNhR/OKu7DyoMZGv bcZM1pfJVzO9vlu5rNJps85Dd87H8DkPNn4TNtFp/QsxTBYtk3g6uXVbA3DO7Q== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1712608185; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=FnxIbTY7ZAI8aFN3M4WSzO7ErldGp7JIm94hjjxe6I0=; b=XdH2T3hm1mGuD3E0fUCTMCUwRVAK/HWsr/SXTFGsOydPoOSwA/vc/RK1tdjr+gAmYpLxyQ 8MWF8yjWy3wYmj6TY+0uhCNGUeHQ6W+Vz2AwHuIaCtb4VfwIi7jg78qmdjW4E7hwOraNSh X2SrtvTWu9UknvhOsCG7FC+tTJssvkwSBceDzSkxKu1StBo1oMqVhPbLYRWab0IT5t/eLp HKcoq70hIoVL7Ug88Zr6TOem1MxHObNUGR0CS6ijFEm4PWDrDVCVV1GrjNA40DLUaDbG5r cb04r5I947AfkcGa3w2pGiznM+1eOiAF0jf9N2CHh3b3W+KfSiOvEtf10qkM2g== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4VD10n3D22zQc9; Mon, 8 Apr 2024 20:29:45 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 438KTjvm041732; Mon, 8 Apr 2024 20:29:45 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 438KTjOa041729; Mon, 8 Apr 2024 20:29:45 GMT (envelope-from git) Date: Mon, 8 Apr 2024 20:29:45 GMT Message-Id: <202404082029.438KTjOa041729@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Gleb Smirnoff Subject: git: fd01798fc48d - main - mbuf: add mc_split() that works on two struct mchain List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: dev-commits-src-main@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: glebius X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: fd01798fc48d2e1dbf0eb42aaa97838515bc5268 Auto-Submitted: auto-generated The branch main has been updated by glebius: URL: https://cgit.FreeBSD.org/src/commit/?id=fd01798fc48d2e1dbf0eb42aaa97838515bc5268 commit fd01798fc48d2e1dbf0eb42aaa97838515bc5268 Author: Gleb Smirnoff AuthorDate: 2024-04-08 20:16:51 +0000 Commit: Gleb Smirnoff CommitDate: 2024-04-08 20:16:51 +0000 mbuf: add mc_split() that works on two struct mchain It preserves tail points and all length/memory accounting, so that caller doesn't need to do any extra traversals. It doesn't respect M_PKTHDR but it may be improved if needed. It respects M_EOR, though. First consumer will be the new unix(4) SOCK_STREAM and SOCK_SEQPACKET. Also provide much more simple mc_concat() that glues two chains back. Reviewed by: markj Differentail Revision: https://reviews.freebsd.org/D44148 --- sys/kern/uipc_mbuf.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++ sys/sys/mbuf.h | 11 +++++++++ 2 files changed, 77 insertions(+) diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c index 5125ad902c34..2593238d5445 100644 --- a/sys/kern/uipc_mbuf.c +++ b/sys/kern/uipc_mbuf.c @@ -1108,6 +1108,72 @@ extpacket: m->m_next = NULL; return (n); } + +/* + * Partition mchain in two pieces, keeping len0 bytes in head and transferring + * remainder to tail. In case of failure, both chains to be left untouched. + * M_EOR is observed correctly. + * Resulting mbufs might be read-only. + */ +int +mc_split(struct mchain *head, struct mchain *tail, u_int len0, int wait) +{ + struct mbuf *m, *n; + u_int len, mlen, remain; + + MPASS(!(mc_first(head)->m_flags & M_PKTHDR)); + MBUF_CHECKSLEEP(wait); + + mlen = 0; + len = len0; + STAILQ_FOREACH(m, &head->mc_q, m_stailq) { + mlen += MSIZE; + if (m->m_flags & M_EXT) + mlen += m->m_ext.ext_size; + if (len > m->m_len) + len -= m->m_len; + else + break; + } + if (__predict_false(m == NULL)) { + *tail = MCHAIN_INITIALIZER(tail); + return (0); + } + remain = m->m_len - len; + if (remain > 0) { + if (__predict_false((n = m_get(wait, m->m_type)) == NULL)) + return (ENOMEM); + m_align(n, remain); + if (m->m_flags & M_EXT) { + n->m_data = m->m_data + len; + mb_dupcl(n, m); + } else + bcopy(mtod(m, char *) + len, mtod(n, char *), remain); + } + + /* XXXGL: need STAILQ_SPLIT */ + STAILQ_FIRST(&tail->mc_q) = STAILQ_NEXT(m, m_stailq); + tail->mc_q.stqh_last = head->mc_q.stqh_last; + tail->mc_len = head->mc_len - len0; + tail->mc_mlen = head->mc_mlen - mlen; + if (remain > 0) { + MPASS(n->m_len == 0); + mc_prepend(tail, n); + n->m_len = remain; + m->m_len -= remain; + if (m->m_flags & M_EOR) { + m->m_flags &= ~M_EOR; + n->m_flags |= M_EOR; + } + } + head->mc_q.stqh_last = &STAILQ_NEXT(m, m_stailq); + STAILQ_NEXT(m, m_stailq) = NULL; + head->mc_len = len0; + head->mc_mlen = mlen; + + return (0); +} + /* * Routine to copy from device local memory into mbufs. * Note that `off' argument is offset into first mbuf of target chain from diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h index 823b56295c2f..a5af2291123b 100644 --- a/sys/sys/mbuf.h +++ b/sys/sys/mbuf.h @@ -1775,6 +1775,15 @@ mc_append(struct mchain *mc, struct mbuf *m) mc_inc(mc, m); } +static inline void +mc_concat(struct mchain *head, struct mchain *tail) +{ + STAILQ_CONCAT(&head->mc_q, &tail->mc_q); + head->mc_len += tail->mc_len; + head->mc_mlen += tail->mc_mlen; + tail->mc_len = tail->mc_mlen = 0; +} + /* * Note: STAILQ_REMOVE() is expensive. mc_remove_after() needs to be provided * as long as there consumers that would benefit from it. @@ -1786,6 +1795,8 @@ mc_remove(struct mchain *mc, struct mbuf *m) mc_dec(mc, m); } +int mc_split(struct mchain *, struct mchain *, u_int, int); + #ifdef _SYS_TIMESPEC_H_ static inline void mbuf_tstmp2timespec(struct mbuf *m, struct timespec *ts)