git: 31df8ff73e3a - main - cxgbei: Rework the pdu_append_data hook to support M_WAITOK.
John Baldwin
jhb at FreeBSD.org
Fri May 14 19:21:57 UTC 2021
The branch main has been updated by jhb:
URL: https://cgit.FreeBSD.org/src/commit/?id=31df8ff73e3aa809146fae9baa6a96e1adf8526b
commit 31df8ff73e3aa809146fae9baa6a96e1adf8526b
Author: John Baldwin <jhb at FreeBSD.org>
AuthorDate: 2021-05-14 19:17:14 +0000
Commit: John Baldwin <jhb at FreeBSD.org>
CommitDate: 2021-05-14 19:17:14 +0000
cxgbei: Rework the pdu_append_data hook to support M_WAITOK.
- Only allocate 16K jumbo mbufs if the region of data to be
appended is sufficiently large, and use a loop.
- Use m_getm2() to allocate a chain for data less than 16K, or
if m_getjcl() fails.
- Use ENOMEM as the return value instead of '1' if the hook fails due
to a memory allocation error.
Sponsored by: Chelsio Communications
Differential Revision: https://reviews.freebsd.org/D29909
---
sys/dev/cxgbe/cxgbei/icl_cxgbei.c | 65 ++++++++++++++++++++++++++++++---------
1 file changed, 50 insertions(+), 15 deletions(-)
diff --git a/sys/dev/cxgbe/cxgbei/icl_cxgbei.c b/sys/dev/cxgbe/cxgbei/icl_cxgbei.c
index 5770599eeeef..f91b9ee38616 100644
--- a/sys/dev/cxgbe/cxgbei/icl_cxgbei.c
+++ b/sys/dev/cxgbe/cxgbei/icl_cxgbei.c
@@ -324,35 +324,70 @@ int
icl_cxgbei_conn_pdu_append_data(struct icl_conn *ic, struct icl_pdu *ip,
const void *addr, size_t len, int flags)
{
- struct mbuf *m;
#ifdef INVARIANTS
struct icl_cxgbei_pdu *icp = ip_to_icp(ip);
#endif
+ struct mbuf *m, *m_tail;
+ const char *src;
MPASS(icp->icp_signature == CXGBEI_PDU_SIGNATURE);
MPASS(ic == ip->ip_conn);
KASSERT(len > 0, ("%s: len is %jd", __func__, (intmax_t)len));
- m = ip->ip_data_mbuf;
- if (m == NULL) {
+ m_tail = ip->ip_data_mbuf;
+ if (m_tail != NULL)
+ for (; m_tail->m_next != NULL; m_tail = m_tail->m_next)
+ ;
+
+ src = (const char *)addr;
+
+ /* Allocate as jumbo mbufs of size MJUM16BYTES. */
+ while (len >= MJUM16BYTES) {
m = m_getjcl(M_NOWAIT, MT_DATA, 0, MJUM16BYTES);
- if (__predict_false(m == NULL))
+ if (__predict_false(m == NULL)) {
+ if ((flags & M_WAITOK) != 0) {
+ /* Fall back to non-jumbo mbufs. */
+ break;
+ }
return (ENOMEM);
-
- ip->ip_data_mbuf = m;
+ }
+ memcpy(mtod(m, void *), src, MJUM16BYTES);
+ m->m_len = MJUM16BYTES;
+ if (ip->ip_data_mbuf == NULL) {
+ ip->ip_data_mbuf = m_tail = m;
+ ip->ip_data_len = MJUM16BYTES;
+ } else {
+ m_tail->m_next = m;
+ m_tail = m_tail->m_next;
+ ip->ip_data_len += MJUM16BYTES;
+ }
+ src += MJUM16BYTES;
+ len -= MJUM16BYTES;
}
- if (__predict_true(m_append(m, len, addr) != 0)) {
- ip->ip_data_len += len;
- MPASS(ip->ip_data_len <= ic->ic_max_data_segment_length);
- return (0);
- } else {
- if (flags & M_WAITOK) {
- CXGBE_UNIMPLEMENTED("fail safe append");
+ /* Allocate mbuf chain for the remaining data. */
+ if (len != 0) {
+ m = m_getm2(NULL, len, flags, MT_DATA, 0);
+ if (__predict_false(m == NULL))
+ return (ENOMEM);
+ if (ip->ip_data_mbuf == NULL) {
+ ip->ip_data_mbuf = m;
+ ip->ip_data_len = len;
+ } else {
+ m_tail->m_next = m;
+ ip->ip_data_len += len;
}
- ip->ip_data_len = m_length(m, NULL);
- return (1);
+ for (; m != NULL; m = m->m_next) {
+ m->m_len = min(len, M_SIZE(m));
+ memcpy(mtod(m, void *), src, m->m_len);
+ src += m->m_len;
+ len -= m->m_len;
+ }
+ MPASS(len == 0);
}
+ MPASS(ip->ip_data_len <= ic->ic_max_data_segment_length);
+
+ return (0);
}
void
More information about the dev-commits-src-main
mailing list