Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/sys/kern/uipc_mbuf.c,v rcsdiff: /ftp/cvs/cvsroot/src/sys/kern/uipc_mbuf.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.159 retrieving revision 1.159.2.5 diff -u -p -r1.159 -r1.159.2.5 --- src/sys/kern/uipc_mbuf.c 2014/11/27 03:15:51 1.159 +++ src/sys/kern/uipc_mbuf.c 2016/07/09 20:25:20 1.159.2.5 @@ -1,4 +1,4 @@ -/* $NetBSD: uipc_mbuf.c,v 1.159 2014/11/27 03:15:51 ozaki-r Exp $ */ +/* $NetBSD: uipc_mbuf.c,v 1.159.2.5 2016/07/09 20:25:20 skrll Exp $ */ /*- * Copyright (c) 1999, 2001 The NetBSD Foundation, Inc. @@ -62,11 +62,13 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: uipc_mbuf.c,v 1.159 2014/11/27 03:15:51 ozaki-r Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uipc_mbuf.c,v 1.159.2.5 2016/07/09 20:25:20 skrll Exp $"); +#ifdef _KERNEL_OPT #include "opt_mbuftrace.h" #include "opt_nmbclusters.h" #include "opt_ddb.h" +#endif #include #include @@ -543,6 +545,7 @@ m_reclaim(void *arg, int flags) { struct domain *dp; const struct protosw *pr; + struct ifnet *ifp; int s; KERNEL_LOCK(1, NULL); @@ -553,7 +556,23 @@ m_reclaim(void *arg, int flags) if (pr->pr_drain) (*pr->pr_drain)(); } - if_drain_all(); + /* XXX we cannot use psref in H/W interrupt */ + if (!cpu_intr_p()) { + int bound = curlwp_bind(); + IFNET_READER_FOREACH(ifp) { + struct psref psref; + + psref_acquire(&psref, &ifp->if_psref, + ifnet_psref_class); + + if (ifp->if_drain) + (*ifp->if_drain)(ifp); + + psref_release(&psref, &ifp->if_psref, + ifnet_psref_class); + } + curlwp_bindx(bound); + } splx(s); mbstat.m_drain++; KERNEL_UNLOCK_ONE(NULL); @@ -577,14 +596,8 @@ m_get(int nowait, int type) return NULL; mbstat_type_add(type, 1); - mowner_init(m, type); - m->m_ext_ref = m; - m->m_type = type; - m->m_len = 0; - m->m_next = NULL; - m->m_nextpkt = NULL; - m->m_data = m->m_dat; - m->m_flags = 0; + + m_hdr_init(m, type, NULL, m->m_dat, 0); return m; } @@ -598,13 +611,7 @@ m_gethdr(int nowait, int type) if (m == NULL) return NULL; - m->m_data = m->m_pktdat; - m->m_flags = M_PKTHDR; - m->m_pkthdr.rcvif = NULL; - m->m_pkthdr.len = 0; - m->m_pkthdr.csum_flags = 0; - m->m_pkthdr.csum_data = 0; - SLIST_INIT(&m->m_pkthdr.tags); + m_pkthdr_init(m); return m; } @@ -773,8 +780,13 @@ m_copym0(struct mbuf *m, int off0, int l /* * we are unsure about the way m was allocated. * copy into multiple MCLBYTES cluster mbufs. + * + * recompute m_len, it is no longer valid if MCLGET() + * fails to allocate a cluster. Then we try to split + * the source into normal sized mbufs. */ MCLGET(n, wait); + n->m_len = 0; n->m_len = M_TRAILINGSPACE(n); n->m_len = m_copylen(len, n->m_len); n->m_len = min(n->m_len, m->m_len - off); @@ -1158,7 +1170,7 @@ m_split0(struct mbuf *m0, int len0, int if (n == NULL) return NULL; MCLAIM(n, m0->m_owner); - n->m_pkthdr.rcvif = m0->m_pkthdr.rcvif; + m_copy_rcvif(n, m0); n->m_pkthdr.len = m0->m_pkthdr.len - len0; len_save = m0->m_pkthdr.len; m0->m_pkthdr.len = len0; @@ -1227,7 +1239,7 @@ m_devget(char *buf, int totlen, int off0 m = m_gethdr(M_DONTWAIT, MT_DATA); if (m == NULL) return NULL; - m->m_pkthdr.rcvif = ifp; + m_set_rcvif(m, ifp); m->m_pkthdr.len = totlen; m->m_len = MHLEN; @@ -1680,7 +1692,7 @@ m_getptr(struct mbuf *m, int loc, int *o /* * m_ext_free: release a reference to the mbuf external storage. * - * => free the mbuf m itsself as well. + * => free the mbuf m itself as well. */ void @@ -1770,7 +1782,7 @@ nextchain: snprintb(buf, sizeof(buf), M_CSUM_BITS, m->m_pkthdr.csum_flags); (*pr)(" pktlen=%d, rcvif=%p, csum_flags=0x%s, csum_data=0x%" PRIx32 ", segsz=%u\n", - m->m_pkthdr.len, m->m_pkthdr.rcvif, + m->m_pkthdr.len, m_get_rcvif_NOMPSAFE(m), buf, m->m_pkthdr.csum_data, m->m_pkthdr.segsz); } if ((m->m_flags & M_EXT)) {