From 92d70a24ca60cebbd66387f373e8ff9caca80b51 Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Fri, 28 Dec 2018 15:28:40 -0500 Subject: [PATCH] freebsd_network: Fix and implement some mbuf functions. Spotted while reviewing the code during iflib porting. --- .../compat/freebsd_network/compat/sys/mbuf.h | 5 +- .../compat/freebsd_network/fbsd_kern_mbuf.c | 58 +++++++++++++++++++ src/libs/compat/freebsd_network/mbuf.c | 28 ++------- 3 files changed, 67 insertions(+), 24 deletions(-) diff --git a/src/libs/compat/freebsd_network/compat/sys/mbuf.h b/src/libs/compat/freebsd_network/compat/sys/mbuf.h index 054c9b01e4..c10405a881 100644 --- a/src/libs/compat/freebsd_network/compat/sys/mbuf.h +++ b/src/libs/compat/freebsd_network/compat/sys/mbuf.h @@ -294,8 +294,9 @@ int m_dup_pkthdr(struct mbuf *to, const struct mbuf *from, int how); void m_demote_pkthdr(struct mbuf *m); void m_demote(struct mbuf *m0, int all, int flags); -void m_extadd(struct mbuf*, caddr_t, u_int, void(*) (void*, void*), - void*, void*, int, int); +void m_extadd(struct mbuf *mb, caddr_t buf, u_int size, + void (*freef)(struct mbuf *, void *, void *), void *arg1, void *arg2, + int flags, int type); u_int m_fixhdr(struct mbuf*); struct mbuf* m_free(struct mbuf*); diff --git a/src/libs/compat/freebsd_network/fbsd_kern_mbuf.c b/src/libs/compat/freebsd_network/fbsd_kern_mbuf.c index ee972f5dc3..0960d250f2 100644 --- a/src/libs/compat/freebsd_network/fbsd_kern_mbuf.c +++ b/src/libs/compat/freebsd_network/fbsd_kern_mbuf.c @@ -95,3 +95,61 @@ m_getm2(struct mbuf *m, int len, int how, short type, int flags) return (m); } +/*- + * Configure a provided mbuf to refer to the provided external storage + * buffer and setup a reference count for said buffer. + * + * Arguments: + * mb The existing mbuf to which to attach the provided buffer. + * buf The address of the provided external storage buffer. + * size The size of the provided buffer. + * freef A pointer to a routine that is responsible for freeing the + * provided external storage buffer. + * args A pointer to an argument structure (of any type) to be passed + * to the provided freef routine (may be NULL). + * flags Any other flags to be passed to the provided mbuf. + * type The type that the external storage buffer should be + * labeled with. + * + * Returns: + * Nothing. + */ +void +m_extadd(struct mbuf *mb, caddr_t buf, u_int size, + void (*freef)(struct mbuf *, void *, void *), void *arg1, void *arg2, + int flags, int type) +{ + + KASSERT(type != EXT_CLUSTER, ("%s: EXT_CLUSTER not allowed", __func__)); + + mb->m_flags |= (M_EXT | flags); + mb->m_ext.ext_buf = buf; + mb->m_data = mb->m_ext.ext_buf; + mb->m_ext.ext_size = size; +#ifndef __HAIKU__ + mb->m_ext.ext_free = freef; + mb->m_ext.ext_arg1 = arg1; + mb->m_ext.ext_arg2 = arg2; +#else + if (freef != NULL) + panic("m_ext.ext_free not yet implemented"); +#endif + mb->m_ext.ext_type = type; + + if (type != EXT_EXTREF) { + mb->m_ext.ext_count = 1; + mb->m_ext.ext_flags = EXT_FLAG_EMBREF; + } else + mb->m_ext.ext_flags = 0; +} + +/* + * Free an entire chain of mbufs and associated external buffers, if + * applicable. + */ +void +m_freem(struct mbuf *mb) +{ + while (mb != NULL) + mb = m_free(mb); +} diff --git a/src/libs/compat/freebsd_network/mbuf.c b/src/libs/compat/freebsd_network/mbuf.c index 4aa37b8a91..5b7dabd107 100644 --- a/src/libs/compat/freebsd_network/mbuf.c +++ b/src/libs/compat/freebsd_network/mbuf.c @@ -214,15 +214,6 @@ m_cljget(struct mbuf *memoryBuffer, int how, int size) return NULL; } - -void -m_freem(struct mbuf *memoryBuffer) -{ - while (memoryBuffer) - memoryBuffer = m_free(memoryBuffer); -} - - static void mb_free_ext(struct mbuf *memoryBuffer) { @@ -272,7 +263,7 @@ mb_free_ext(struct mbuf *memoryBuffer) else if (memoryBuffer->m_ext.ext_type == EXT_JUMBOP) cache = sJumboPageSizeCache; else - panic("unknown type"); + panic("unknown mbuf ext_type %d", memoryBuffer->m_ext.ext_type); object_cache_free(cache, memoryBuffer->m_ext.ext_buf, 0); memoryBuffer->m_ext.ext_buf = NULL; @@ -281,28 +272,21 @@ mb_free_ext(struct mbuf *memoryBuffer) struct mbuf * -m_free(struct mbuf *memoryBuffer) +m_free(struct mbuf* memoryBuffer) { - struct mbuf *next = memoryBuffer->m_next; + struct mbuf* next = memoryBuffer->m_next; + if ((memoryBuffer->m_flags & (M_PKTHDR|M_NOFREE)) == (M_PKTHDR|M_NOFREE)) + m_tag_delete_chain(memoryBuffer, NULL); if (memoryBuffer->m_flags & M_EXT) mb_free_ext(memoryBuffer); - else + else if ((memoryBuffer->m_flags & M_NOFREE) == 0) object_cache_free(sMBufCache, memoryBuffer, 0); return next; } -void -m_extadd(struct mbuf *memoryBuffer, caddr_t buffer, u_int size, - void (*freeHook)(void *, void *), void *arg1, void *arg2, int flags, int type) -{ - // TODO: implement? - panic("m_extadd() called."); -} - - status_t init_mbufs() {