Changeset View
Changeset View
Standalone View
Standalone View
sys/sys/mbuf.h
Show First 20 Lines • Show All 154 Lines • ▼ Show 20 Lines | |||||
* Description of external storage mapped into mbuf; valid only if M_EXT is | * Description of external storage mapped into mbuf; valid only if M_EXT is | ||||
* set. | * set. | ||||
* Size ILP32: 28 | * Size ILP32: 28 | ||||
* LP64: 48 | * LP64: 48 | ||||
* Compile-time assertions in uipc_mbuf.c test these values to ensure that | * Compile-time assertions in uipc_mbuf.c test these values to ensure that | ||||
* they are correct. | * they are correct. | ||||
*/ | */ | ||||
struct m_ext { | struct m_ext { | ||||
union { | |||||
volatile u_int ext_count; /* value of ref count info */ | |||||
volatile u_int *ext_cnt; /* pointer to ref count info */ | volatile u_int *ext_cnt; /* pointer to ref count info */ | ||||
}; | |||||
caddr_t ext_buf; /* start of buffer */ | caddr_t ext_buf; /* start of buffer */ | ||||
uint32_t ext_size; /* size of buffer, for ext_free */ | uint32_t ext_size; /* size of buffer, for ext_free */ | ||||
uint32_t ext_type:8, /* type of external storage */ | uint32_t ext_type:8, /* type of external storage */ | ||||
ext_flags:24; /* external storage mbuf flags */ | ext_flags:24; /* external storage mbuf flags */ | ||||
void (*ext_free) /* free routine if not the usual */ | void (*ext_free) /* free routine if not the usual */ | ||||
(struct mbuf *, void *, void *); | (struct mbuf *, void *, void *); | ||||
void *ext_arg1; /* optional argument pointer */ | void *ext_arg1; /* optional argument pointer */ | ||||
void *ext_arg2; /* optional argument pointer */ | void *ext_arg2; /* optional argument pointer */ | ||||
▲ Show 20 Lines • Show All 193 Lines • ▼ Show 20 Lines | |||||
#define EXT_MOD_TYPE 253 /* custom module's ext_buf type */ | #define EXT_MOD_TYPE 253 /* custom module's ext_buf type */ | ||||
#define EXT_DISPOSABLE 254 /* can throw this buffer away w/page flipping */ | #define EXT_DISPOSABLE 254 /* can throw this buffer away w/page flipping */ | ||||
#define EXT_EXTREF 255 /* has externally maintained ext_cnt ptr */ | #define EXT_EXTREF 255 /* has externally maintained ext_cnt ptr */ | ||||
/* | /* | ||||
* Flags for external mbuf buffer types. | * Flags for external mbuf buffer types. | ||||
* NB: limited to the lower 24 bits. | * NB: limited to the lower 24 bits. | ||||
*/ | */ | ||||
#define EXT_FLAG_EMBREF 0x000001 /* embedded ext_cnt, notyet */ | #define EXT_FLAG_EMBREF 0x000001 /* embedded ext_count */ | ||||
#define EXT_FLAG_EXTREF 0x000002 /* external ext_cnt, notyet */ | #define EXT_FLAG_EXTREF 0x000002 /* external ext_cnt, notyet */ | ||||
#define EXT_FLAG_NOFREE 0x000010 /* don't free mbuf to pool, notyet */ | #define EXT_FLAG_NOFREE 0x000010 /* don't free mbuf to pool, notyet */ | ||||
#define EXT_FLAG_VENDOR1 0x010000 /* for vendor-internal use */ | #define EXT_FLAG_VENDOR1 0x010000 /* for vendor-internal use */ | ||||
#define EXT_FLAG_VENDOR2 0x020000 /* for vendor-internal use */ | #define EXT_FLAG_VENDOR2 0x020000 /* for vendor-internal use */ | ||||
#define EXT_FLAG_VENDOR3 0x040000 /* for vendor-internal use */ | #define EXT_FLAG_VENDOR3 0x040000 /* for vendor-internal use */ | ||||
#define EXT_FLAG_VENDOR4 0x080000 /* for vendor-internal use */ | #define EXT_FLAG_VENDOR4 0x080000 /* for vendor-internal use */ | ||||
Show All 9 Lines | #define EXT_FLAG_BITS \ | ||||
"\20\1EXT_FLAG_EMBREF\2EXT_FLAG_EXTREF\5EXT_FLAG_NOFREE" \ | "\20\1EXT_FLAG_EMBREF\2EXT_FLAG_EXTREF\5EXT_FLAG_NOFREE" \ | ||||
"\21EXT_FLAG_VENDOR1\22EXT_FLAG_VENDOR2\23EXT_FLAG_VENDOR3" \ | "\21EXT_FLAG_VENDOR1\22EXT_FLAG_VENDOR2\23EXT_FLAG_VENDOR3" \ | ||||
"\24EXT_FLAG_VENDOR4\25EXT_FLAG_EXP1\26EXT_FLAG_EXP2\27EXT_FLAG_EXP3" \ | "\24EXT_FLAG_VENDOR4\25EXT_FLAG_EXP1\26EXT_FLAG_EXP2\27EXT_FLAG_EXP3" \ | ||||
"\30EXT_FLAG_EXP4" | "\30EXT_FLAG_EXP4" | ||||
/* | /* | ||||
* External reference/free functions. | * External reference/free functions. | ||||
*/ | */ | ||||
void sf_ext_ref(void *, void *); | |||||
void sf_ext_free(void *, void *); | void sf_ext_free(void *, void *); | ||||
void sf_ext_free_nocache(void *, void *); | void sf_ext_free_nocache(void *, void *); | ||||
/* | /* | ||||
* Flags indicating checksum, segmentation and other offload work to be | * Flags indicating checksum, segmentation and other offload work to be | ||||
* done, or already done, by hardware or lower layers. It is split into | * done, or already done, by hardware or lower layers. It is split into | ||||
* separate inbound and outbound flags. | * separate inbound and outbound flags. | ||||
* | * | ||||
▲ Show 20 Lines • Show All 111 Lines • ▼ Show 20 Lines | |||||
* The rest of it is defined in kern/kern_mbuf.c | * The rest of it is defined in kern/kern_mbuf.c | ||||
*/ | */ | ||||
extern uma_zone_t zone_mbuf; | extern uma_zone_t zone_mbuf; | ||||
extern uma_zone_t zone_clust; | extern uma_zone_t zone_clust; | ||||
extern uma_zone_t zone_pack; | extern uma_zone_t zone_pack; | ||||
extern uma_zone_t zone_jumbop; | extern uma_zone_t zone_jumbop; | ||||
extern uma_zone_t zone_jumbo9; | extern uma_zone_t zone_jumbo9; | ||||
extern uma_zone_t zone_jumbo16; | extern uma_zone_t zone_jumbo16; | ||||
extern uma_zone_t zone_ext_refcnt; | |||||
void mb_dupcl(struct mbuf *, const struct mbuf *); | void mb_dupcl(struct mbuf *, struct mbuf *); | ||||
void mb_free_ext(struct mbuf *); | void mb_free_ext(struct mbuf *); | ||||
void m_adj(struct mbuf *, int); | void m_adj(struct mbuf *, int); | ||||
int m_apply(struct mbuf *, int, int, | int m_apply(struct mbuf *, int, int, | ||||
int (*)(void *, void *, u_int), void *); | int (*)(void *, void *, u_int), void *); | ||||
int m_append(struct mbuf *, int, c_caddr_t); | int m_append(struct mbuf *, int, c_caddr_t); | ||||
void m_cat(struct mbuf *, struct mbuf *); | void m_cat(struct mbuf *, struct mbuf *); | ||||
void m_catpkt(struct mbuf *, struct mbuf *); | void m_catpkt(struct mbuf *, struct mbuf *); | ||||
int m_clget(struct mbuf *m, int how); | int m_clget(struct mbuf *m, int how); | ||||
void *m_cljget(struct mbuf *m, int how, int size); | void *m_cljget(struct mbuf *m, int how, int size); | ||||
struct mbuf *m_collapse(struct mbuf *, int, int); | struct mbuf *m_collapse(struct mbuf *, int, int); | ||||
void m_copyback(struct mbuf *, int, int, c_caddr_t); | void m_copyback(struct mbuf *, int, int, c_caddr_t); | ||||
void m_copydata(const struct mbuf *, int, int, caddr_t); | void m_copydata(const struct mbuf *, int, int, caddr_t); | ||||
struct mbuf *m_copym(const struct mbuf *, int, int, int); | struct mbuf *m_copym(struct mbuf *, int, int, int); | ||||
struct mbuf *m_copypacket(struct mbuf *, int); | struct mbuf *m_copypacket(struct mbuf *, int); | ||||
void m_copy_pkthdr(struct mbuf *, struct mbuf *); | void m_copy_pkthdr(struct mbuf *, struct mbuf *); | ||||
struct mbuf *m_copyup(struct mbuf *, int, int); | struct mbuf *m_copyup(struct mbuf *, int, int); | ||||
struct mbuf *m_defrag(struct mbuf *, int); | struct mbuf *m_defrag(struct mbuf *, int); | ||||
void m_demote_pkthdr(struct mbuf *); | void m_demote_pkthdr(struct mbuf *); | ||||
void m_demote(struct mbuf *, int, int); | void m_demote(struct mbuf *, int, int); | ||||
struct mbuf *m_devget(char *, int, int, struct ifnet *, | struct mbuf *m_devget(char *, int, int, struct ifnet *, | ||||
void (*)(char *, caddr_t, u_int)); | void (*)(char *, caddr_t, u_int)); | ||||
struct mbuf *m_dup(const struct mbuf *, int); | struct mbuf *m_dup(const struct mbuf *, int); | ||||
int m_dup_pkthdr(struct mbuf *, const struct mbuf *, int); | int m_dup_pkthdr(struct mbuf *, const struct mbuf *, int); | ||||
int m_extadd(struct mbuf *, caddr_t, u_int, | void m_extadd(struct mbuf *, caddr_t, u_int, | ||||
void (*)(struct mbuf *, void *, void *), void *, void *, | void (*)(struct mbuf *, void *, void *), void *, void *, | ||||
int, int, int); | int, int); | ||||
u_int m_fixhdr(struct mbuf *); | u_int m_fixhdr(struct mbuf *); | ||||
struct mbuf *m_fragment(struct mbuf *, int, int); | struct mbuf *m_fragment(struct mbuf *, int, int); | ||||
void m_freem(struct mbuf *); | void m_freem(struct mbuf *); | ||||
struct mbuf *m_get2(int, int, short, int); | struct mbuf *m_get2(int, int, short, int); | ||||
struct mbuf *m_getjcl(int, short, int, int); | struct mbuf *m_getjcl(int, short, int, int); | ||||
struct mbuf *m_getm2(struct mbuf *, int, int, short, int); | struct mbuf *m_getm2(struct mbuf *, int, int, short, int); | ||||
struct mbuf *m_getptr(struct mbuf *, int, int *); | struct mbuf *m_getptr(struct mbuf *, int, int *); | ||||
u_int m_length(struct mbuf *, struct mbuf **); | u_int m_length(struct mbuf *, struct mbuf **); | ||||
▲ Show 20 Lines • Show All 140 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
struct mb_args args; | struct mb_args args; | ||||
args.flags = flags; | args.flags = flags; | ||||
args.type = type; | args.type = type; | ||||
return (uma_zalloc_arg(zone_pack, &args, how)); | return (uma_zalloc_arg(zone_pack, &args, how)); | ||||
} | } | ||||
/* | |||||
* XXX: m_cljset() is a dangerous API. One must attach only a new, | |||||
* unreferenced cluster to an mbuf(9). It is not possible to assert | |||||
* that, so care can be taken only by users of the API. | |||||
*/ | |||||
static __inline void | static __inline void | ||||
m_cljset(struct mbuf *m, void *cl, int type) | m_cljset(struct mbuf *m, void *cl, int type) | ||||
{ | { | ||||
uma_zone_t zone; | |||||
int size; | int size; | ||||
switch (type) { | switch (type) { | ||||
case EXT_CLUSTER: | case EXT_CLUSTER: | ||||
size = MCLBYTES; | size = MCLBYTES; | ||||
zone = zone_clust; | |||||
break; | break; | ||||
#if MJUMPAGESIZE != MCLBYTES | #if MJUMPAGESIZE != MCLBYTES | ||||
case EXT_JUMBOP: | case EXT_JUMBOP: | ||||
size = MJUMPAGESIZE; | size = MJUMPAGESIZE; | ||||
zone = zone_jumbop; | |||||
break; | break; | ||||
#endif | #endif | ||||
case EXT_JUMBO9: | case EXT_JUMBO9: | ||||
size = MJUM9BYTES; | size = MJUM9BYTES; | ||||
zone = zone_jumbo9; | |||||
break; | break; | ||||
case EXT_JUMBO16: | case EXT_JUMBO16: | ||||
size = MJUM16BYTES; | size = MJUM16BYTES; | ||||
zone = zone_jumbo16; | |||||
break; | break; | ||||
default: | default: | ||||
panic("%s: unknown cluster type %d", __func__, type); | panic("%s: unknown cluster type %d", __func__, type); | ||||
break; | break; | ||||
} | } | ||||
m->m_data = m->m_ext.ext_buf = cl; | m->m_data = m->m_ext.ext_buf = cl; | ||||
m->m_ext.ext_free = m->m_ext.ext_arg1 = m->m_ext.ext_arg2 = NULL; | m->m_ext.ext_free = m->m_ext.ext_arg1 = m->m_ext.ext_arg2 = NULL; | ||||
m->m_ext.ext_size = size; | m->m_ext.ext_size = size; | ||||
m->m_ext.ext_type = type; | m->m_ext.ext_type = type; | ||||
m->m_ext.ext_flags = 0; | m->m_ext.ext_flags = EXT_FLAG_EMBREF; | ||||
m->m_ext.ext_cnt = uma_find_refcnt(zone, cl); | m->m_ext.ext_count = 1; | ||||
m->m_flags |= M_EXT; | m->m_flags |= M_EXT; | ||||
} | } | ||||
static __inline void | static __inline void | ||||
m_chtype(struct mbuf *m, short new_type) | m_chtype(struct mbuf *m, short new_type) | ||||
{ | { | ||||
m->m_type = new_type; | m->m_type = new_type; | ||||
} | } | ||||
Show All 12 Lines | |||||
m_last(struct mbuf *m) | m_last(struct mbuf *m) | ||||
{ | { | ||||
while (m->m_next) | while (m->m_next) | ||||
m = m->m_next; | m = m->m_next; | ||||
return (m); | return (m); | ||||
} | } | ||||
static inline u_int | |||||
m_extrefcnt(struct mbuf *m) | |||||
{ | |||||
KASSERT(m->m_flags & M_EXT, ("%s: M_EXT missing", __func__)); | |||||
return ((m->m_ext.ext_flags & EXT_FLAG_EMBREF) ? m->m_ext.ext_count : | |||||
*m->m_ext.ext_cnt); | |||||
} | |||||
/* | /* | ||||
* mbuf, cluster, and external object allocation macros (for compatibility | * mbuf, cluster, and external object allocation macros (for compatibility | ||||
* purposes). | * purposes). | ||||
*/ | */ | ||||
#define M_MOVE_PKTHDR(to, from) m_move_pkthdr((to), (from)) | #define M_MOVE_PKTHDR(to, from) m_move_pkthdr((to), (from)) | ||||
#define MGET(m, how, type) ((m) = m_get((how), (type))) | #define MGET(m, how, type) ((m) = m_get((how), (type))) | ||||
#define MGETHDR(m, how, type) ((m) = m_gethdr((how), (type))) | #define MGETHDR(m, how, type) ((m) = m_gethdr((how), (type))) | ||||
#define MCLGET(m, how) m_clget((m), (how)) | #define MCLGET(m, how) m_clget((m), (how)) | ||||
#define MEXTADD(m, buf, size, free, arg1, arg2, flags, type) \ | #define MEXTADD(m, buf, size, free, arg1, arg2, flags, type) \ | ||||
(void )m_extadd((m), (caddr_t)(buf), (size), (free), (arg1), (arg2),\ | m_extadd((m), (caddr_t)(buf), (size), (free), (arg1), (arg2), \ | ||||
(flags), (type), M_NOWAIT) | (flags), (type)) | ||||
#define m_getm(m, len, how, type) \ | #define m_getm(m, len, how, type) \ | ||||
m_getm2((m), (len), (how), (type), M_PKTHDR) | m_getm2((m), (len), (how), (type), M_PKTHDR) | ||||
/* | /* | ||||
* Evaluate TRUE if it's safe to write to the mbuf m's data region (this can | * Evaluate TRUE if it's safe to write to the mbuf m's data region (this can | ||||
* be both the local data payload, or an external buffer area, depending on | * be both the local data payload, or an external buffer area, depending on | ||||
* whether M_EXT is set). | * whether M_EXT is set). | ||||
*/ | */ | ||||
#define M_WRITABLE(m) (!((m)->m_flags & M_RDONLY) && \ | #define M_WRITABLE(m) (!((m)->m_flags & M_RDONLY) && \ | ||||
(!(((m)->m_flags & M_EXT)) || \ | (!(((m)->m_flags & M_EXT)) || \ | ||||
(*((m)->m_ext.ext_cnt) == 1)) ) \ | (m_extrefcnt(m) == 1))) | ||||
/* Check if the supplied mbuf has a packet header, or else panic. */ | /* Check if the supplied mbuf has a packet header, or else panic. */ | ||||
#define M_ASSERTPKTHDR(m) \ | #define M_ASSERTPKTHDR(m) \ | ||||
KASSERT((m) != NULL && (m)->m_flags & M_PKTHDR, \ | KASSERT((m) != NULL && (m)->m_flags & M_PKTHDR, \ | ||||
("%s: no mbuf packet header!", __func__)) | ("%s: no mbuf packet header!", __func__)) | ||||
/* | /* | ||||
* Ensure that the supplied mbuf is a valid, non-free mbuf. | * Ensure that the supplied mbuf is a valid, non-free mbuf. | ||||
▲ Show 20 Lines • Show All 446 Lines • Show Last 20 Lines |