From nobody Mon Apr 08 20:29:44 2024 X-Original-To: dev-commits-src-all@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 4VD10m4lRKz5HjSC; Mon, 8 Apr 2024 20:29:44 +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 4VD10m2Xllz462V; Mon, 8 Apr 2024 20:29:44 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1712608184; 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=8mNBDFZ5fTgMm6IMl7L3yVrAF2rN64iP2khBwehkMVk=; b=ZnUMFeyOglZY9YbII4Krzz0UsNtexVOqxk/lX4oDQPDELB8OieLOUtCoTkIHK+90KPdPZ5 3+BbP7wVuPDHyl6JcmKBaBchH6ev+GJrn9iRjy/oHBi2jVBnWWlwFuyXjvZ6fSgy0smxqb C/o2lOcn6+pF9hAh1TvIV+HbSZiGYBstlHwZzVltlBoxocAqAgdmMSjQP3A+cX1r9DN3O1 LOB1R8vPbbkh7EwAiHhJ65/ZRiHLNI6rmIs5tUkiKwvbcz9BeVnJwKoLCvnHD3/9Z6wE/B NxAZTMtZ8hJF14hVntQ03J6pDec+GBlIwO/wuMWEjRAqH3++BfA1uJou1ylJAg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1712608184; a=rsa-sha256; cv=none; b=jPm+AMchAQ63ekczy5mJPrmiSM0gIcjSz2Zta7ZBThDM9MVVUxNSqPM5a8S4mRMzzcdhDB AAG2YgQwz323adaXJjIO4rv23KLcMJ8BMu9zy8032ri+TtlfVHzh77Vw3tT+fNJWIqf9Wk lvj4QUUpAaY9PiLEhd6R6cyk7ZxkFVqjxSaOyXFpg1bMkxyEzglSh/PBxdM13KHF6SuE5w 0JMOLgho28x9mjqPJ9FFaJM6TL038sgZkWYaUl0c0Jc+A0UXF0kvzubluZVCBai3YQsMbP 8XJnBtZ2j1/BaRyUgYXKdBlo79nc+Ehr/RY6Aw+jA0rrzrgSpTJu1OyliKRK0w== 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=1712608184; 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=8mNBDFZ5fTgMm6IMl7L3yVrAF2rN64iP2khBwehkMVk=; b=QGy6nSVUP9MFKiS1046i2gSZuEY8+JSB39YFpcSmJWdwoLAhETzGZg+WYEJgnXtMX8+PM3 0cqMocmtfdFAVMkqOh4I8322yUwcHhSsjhBypKF4Lpl7H+u2LMbG09Qc4+2Sf6mg+iPMdJ p1r5/5t/9LFJ+K+6Z+qtITzCAIzr77K0YzPZAlcaNaJncQkwRtP73qVExmrQKNU5AO/qzv v3xwHRry+JCfNiiYphJSxYFj6SCO7cxN/WZQwhlyZQNF422CQWMp7G71THzTs1bcjAhsma 6Zx7cvOum5kWcYNM5RPDo405U+YfEnm03KBjXS8UXeD0PGGirMCQ7UHzr11hCA== 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 4VD10m29NTzQ29; Mon, 8 Apr 2024 20:29:44 +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 438KTiwD041678; Mon, 8 Apr 2024 20:29:44 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 438KTi5x041675; Mon, 8 Apr 2024 20:29:44 GMT (envelope-from git) Date: Mon, 8 Apr 2024 20:29:44 GMT Message-Id: <202404082029.438KTi5x041675@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: ab8a51c45586 - main - mbuf: provide new type for mbuf manipulation - mbuf chain List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@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: ab8a51c455863d8c7df6155fae3fe2edd507d100 Auto-Submitted: auto-generated The branch main has been updated by glebius: URL: https://cgit.FreeBSD.org/src/commit/?id=ab8a51c455863d8c7df6155fae3fe2edd507d100 commit ab8a51c455863d8c7df6155fae3fe2edd507d100 Author: Gleb Smirnoff AuthorDate: 2024-04-08 20:16:51 +0000 Commit: Gleb Smirnoff CommitDate: 2024-04-08 20:16:51 +0000 mbuf: provide new type for mbuf manipulation - mbuf chain It tracks both the first mbuf and last mbuf, making it handy to use inside functions that are interested in both. It also tracks length of data and memory usage. It can be allocated on stack and passed to an mbuf allocation or another mbuf manipulation function. It can be embedded into some kernel facility internal structure representing most simple data buffer. It uses modern queue(3) based linkage, but is also compatible with old style m_next linkage. Transitioning older code to new type can be done gradually - a code that doesn't understand the chain yet, can be supplied with STAILQ_FIRST(&mc.mc_q). So you can have a mix of old style and new style code in one function as a temporary solution. Reviewed by: markj, tuexen Differential Revision: https://reviews.freebsd.org/D44147 --- sys/sys/mbuf.h | 114 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h index b84898fc268e..823b56295c2f 100644 --- a/sys/sys/mbuf.h +++ b/sys/sys/mbuf.h @@ -1555,6 +1555,10 @@ uint32_t m_infiniband_tcpip_hash(const uint32_t, const struct mbuf *, uint32_t); #define M_PROFILE(m) #endif +/* + * Structure describing a packet queue: mbufs linked by m_stailqpkt. + * Does accounting of number of packets and has a cap. + */ struct mbufq { STAILQ_HEAD(, mbuf) mq_head; int mq_len; @@ -1672,6 +1676,116 @@ mbufq_concat(struct mbufq *mq_dst, struct mbufq *mq_src) mq_src->mq_len = 0; } +/* + * Structure describing a chain of mbufs linked by m_stailq, also tracking + * the pointer to the last. Also does accounting of data length and memory + * usage. + * To be used as an argument to mbuf chain allocation and manipulation KPIs, + * and can be allocated on the stack of a caller. Kernel facilities may use + * it internally as a most simple implementation of a stream data buffer. + */ +struct mchain { + STAILQ_HEAD(, mbuf) mc_q; + u_int mc_len; + u_int mc_mlen; +}; + +#define MCHAIN_INITIALIZER(mc) \ + (struct mchain){ .mc_q = STAILQ_HEAD_INITIALIZER((mc)->mc_q) } + +static inline struct mbuf * +mc_first(struct mchain *mc) +{ + return (STAILQ_FIRST(&mc->mc_q)); +} + +static inline struct mbuf * +mc_last(struct mchain *mc) +{ + return (STAILQ_LAST(&mc->mc_q, mbuf, m_stailq)); +} + +static inline bool +mc_empty(struct mchain *mc) +{ + return (STAILQ_EMPTY(&mc->mc_q)); +} + +/* Account addition of m to mc. */ +static inline void +mc_inc(struct mchain *mc, struct mbuf *m) +{ + mc->mc_len += m->m_len; + mc->mc_mlen += MSIZE; + if (m->m_flags & M_EXT) + mc->mc_mlen += m->m_ext.ext_size; +} + +/* Account removal of m from mc. */ +static inline void +mc_dec(struct mchain *mc, struct mbuf *m) +{ + MPASS(mc->mc_len >= m->m_len); + mc->mc_len -= m->m_len; + MPASS(mc->mc_mlen >= MSIZE); + mc->mc_mlen -= MSIZE; + if (m->m_flags & M_EXT) { + MPASS(mc->mc_mlen >= m->m_ext.ext_size); + mc->mc_mlen -= m->m_ext.ext_size; + } +} + +/* + * Get mchain from a classic mbuf chain linked by m_next. Two hacks here: + * we use the fact that m_next is alias to m_stailq, we use internal queue(3) + * fields. + */ +static inline void +mc_init_m(struct mchain *mc, struct mbuf *m) +{ + struct mbuf *last; + + STAILQ_FIRST(&mc->mc_q) = m; + mc->mc_len = mc->mc_mlen = 0; + STAILQ_FOREACH(m, &mc->mc_q, m_stailq) { + mc_inc(mc, m); + last = m; + } + mc->mc_q.stqh_last = &STAILQ_NEXT(last, m_stailq); +} + +static inline void +mc_freem(struct mchain *mc) +{ + if (!mc_empty(mc)) + m_freem(mc_first(mc)); +} + +static inline void +mc_prepend(struct mchain *mc, struct mbuf *m) +{ + STAILQ_INSERT_HEAD(&mc->mc_q, m, m_stailq); + mc_inc(mc, m); +} + +static inline void +mc_append(struct mchain *mc, struct mbuf *m) +{ + STAILQ_INSERT_TAIL(&mc->mc_q, m, m_stailq); + mc_inc(mc, m); +} + +/* + * Note: STAILQ_REMOVE() is expensive. mc_remove_after() needs to be provided + * as long as there consumers that would benefit from it. + */ +static inline void +mc_remove(struct mchain *mc, struct mbuf *m) +{ + STAILQ_REMOVE(&mc->mc_q, m, mbuf, m_stailq); + mc_dec(mc, m); +} + #ifdef _SYS_TIMESPEC_H_ static inline void mbuf_tstmp2timespec(struct mbuf *m, struct timespec *ts)