Wed Apr 12 06:48:08 2023 UTC ()
mbuf(9): New m_get_n, m_gethdr_n.

m_get_n(how, type, alignbytes, nbytes) returns an mbuf with no packet
header having space for nbytes, with an internal buffer pointer
aligned by alignbytes (typically ETHER_ALIGN or similar, if not
zero).

m_gethdr_n(how, type, alignbytes, nbytes) does the same but for an
mbuf with a packet header.

These return NULL on failure, which can happen either:
(a) because how is M_DONTWAIT and allocating memory would sleep, or
(b) because alignbytes + nbytes > MCLBYTES.

On exit, m_len is set to nbytes, as is m_pkthdr.len for m_gethdr_n.

These should be used to systematically replace all calls to m_get,
m_gethdr, MGET, MGETHDR, and m_getcl.  Most calls to m_clget and
MCLGET will probably evaporate as a consequence.

Proposed on tech-net last year:
https://mail-index.netbsd.org/tech-net/2022/07/16/msg008285.html


(riastradh)
diff -r1.250 -r1.251 src/sys/kern/uipc_mbuf.c
diff -r1.237 -r1.238 src/sys/sys/mbuf.h

cvs diff -r1.250 -r1.251 src/sys/kern/uipc_mbuf.c (expand / switch to unified diff)

--- src/sys/kern/uipc_mbuf.c 2023/04/01 06:30:19 1.250
+++ src/sys/kern/uipc_mbuf.c 2023/04/12 06:48:08 1.251
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: uipc_mbuf.c,v 1.250 2023/04/01 06:30:19 skrll Exp $ */ 1/* $NetBSD: uipc_mbuf.c,v 1.251 2023/04/12 06:48:08 riastradh Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1999, 2001, 2018 The NetBSD Foundation, Inc. 4 * Copyright (c) 1999, 2001, 2018 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9 * NASA Ames Research Center, and Maxime Villard. 9 * NASA Ames Research Center, and Maxime Villard.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
@@ -52,27 +52,27 @@ @@ -52,27 +52,27 @@
52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59 * SUCH DAMAGE. 59 * SUCH DAMAGE.
60 * 60 *
61 * @(#)uipc_mbuf.c 8.4 (Berkeley) 2/14/95 61 * @(#)uipc_mbuf.c 8.4 (Berkeley) 2/14/95
62 */ 62 */
63 63
64#include <sys/cdefs.h> 64#include <sys/cdefs.h>
65__KERNEL_RCSID(0, "$NetBSD: uipc_mbuf.c,v 1.250 2023/04/01 06:30:19 skrll Exp $"); 65__KERNEL_RCSID(0, "$NetBSD: uipc_mbuf.c,v 1.251 2023/04/12 06:48:08 riastradh Exp $");
66 66
67#ifdef _KERNEL_OPT 67#ifdef _KERNEL_OPT
68#include "opt_mbuftrace.h" 68#include "opt_mbuftrace.h"
69#include "opt_nmbclusters.h" 69#include "opt_nmbclusters.h"
70#include "opt_ddb.h" 70#include "opt_ddb.h"
71#include "ether.h" 71#include "ether.h"
72#endif 72#endif
73 73
74#include <sys/param.h> 74#include <sys/param.h>
75#include <sys/systm.h> 75#include <sys/systm.h>
76#include <sys/atomic.h> 76#include <sys/atomic.h>
77#include <sys/cpu.h> 77#include <sys/cpu.h>
78#include <sys/proc.h> 78#include <sys/proc.h>
@@ -577,26 +577,70 @@ m_gethdr(int how, int type) @@ -577,26 +577,70 @@ m_gethdr(int how, int type)
577 m->m_pkthdr.csum_data = 0; 577 m->m_pkthdr.csum_data = 0;
578 m->m_pkthdr.segsz = 0; 578 m->m_pkthdr.segsz = 0;
579 m->m_pkthdr.ether_vtag = 0; 579 m->m_pkthdr.ether_vtag = 0;
580 m->m_pkthdr.pkthdr_flags = 0; 580 m->m_pkthdr.pkthdr_flags = 0;
581 SLIST_INIT(&m->m_pkthdr.tags); 581 SLIST_INIT(&m->m_pkthdr.tags);
582 582
583 m->m_pkthdr.pattr_class = NULL; 583 m->m_pkthdr.pattr_class = NULL;
584 m->m_pkthdr.pattr_af = AF_UNSPEC; 584 m->m_pkthdr.pattr_af = AF_UNSPEC;
585 m->m_pkthdr.pattr_hdr = NULL; 585 m->m_pkthdr.pattr_hdr = NULL;
586 586
587 return m; 587 return m;
588} 588}
589 589
 590struct mbuf *
 591m_get_n(int how, int type, size_t alignbytes, size_t nbytes)
 592{
 593 struct mbuf *m;
 594
 595 if (alignbytes > MCLBYTES || nbytes > MCLBYTES - alignbytes)
 596 return NULL;
 597 if ((m = m_get(how, type)) == NULL)
 598 return NULL;
 599 if (nbytes + alignbytes > MLEN) {
 600 m_clget(m, how);
 601 if ((m->m_flags & M_EXT) == 0) {
 602 m_free(m);
 603 return NULL;
 604 }
 605 }
 606 m->m_len = alignbytes + nbytes;
 607 m_adj(m, alignbytes);
 608
 609 return m;
 610}
 611
 612struct mbuf *
 613m_gethdr_n(int how, int type, size_t alignbytes, size_t nbytes)
 614{
 615 struct mbuf *m;
 616
 617 if (nbytes > MCLBYTES || nbytes > MCLBYTES - alignbytes)
 618 return NULL;
 619 if ((m = m_gethdr(how, type)) == NULL)
 620 return NULL;
 621 if (alignbytes + nbytes > MHLEN) {
 622 m_clget(m, how);
 623 if ((m->m_flags & M_EXT) == 0) {
 624 m_free(m);
 625 return NULL;
 626 }
 627 }
 628 m->m_len = m->m_pkthdr.len = alignbytes + nbytes;
 629 m_adj(m, alignbytes);
 630
 631 return m;
 632}
 633
590void 634void
591m_clget(struct mbuf *m, int how) 635m_clget(struct mbuf *m, int how)
592{ 636{
593 m->m_ext_storage.ext_buf = (char *)pool_cache_get_paddr(mcl_cache, 637 m->m_ext_storage.ext_buf = (char *)pool_cache_get_paddr(mcl_cache,
594 how == M_WAIT ? (PR_WAITOK|PR_LIMITFAIL) : PR_NOWAIT, 638 how == M_WAIT ? (PR_WAITOK|PR_LIMITFAIL) : PR_NOWAIT,
595 &m->m_ext_storage.ext_paddr); 639 &m->m_ext_storage.ext_paddr);
596 640
597 if (m->m_ext_storage.ext_buf == NULL) 641 if (m->m_ext_storage.ext_buf == NULL)
598 return; 642 return;
599 643
600 KASSERTMSG((((vaddr_t)m->m_ext_storage.ext_buf & PAGE_MASK) + mclbytes 644 KASSERTMSG((((vaddr_t)m->m_ext_storage.ext_buf & PAGE_MASK) + mclbytes
601 <= PAGE_SIZE), 645 <= PAGE_SIZE),
602 "m=%p m->m_ext_storage.ext_buf=%p" 646 "m=%p m->m_ext_storage.ext_buf=%p"

cvs diff -r1.237 -r1.238 src/sys/sys/mbuf.h (expand / switch to unified diff)

--- src/sys/sys/mbuf.h 2022/12/16 08:42:55 1.237
+++ src/sys/sys/mbuf.h 2023/04/12 06:48:08 1.238
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: mbuf.h,v 1.237 2022/12/16 08:42:55 msaitoh Exp $ */ 1/* $NetBSD: mbuf.h,v 1.238 2023/04/12 06:48:08 riastradh Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1996, 1997, 1999, 2001, 2007 The NetBSD Foundation, Inc. 4 * Copyright (c) 1996, 1997, 1999, 2001, 2007 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9 * NASA Ames Research Center and Matt Thomas of 3am Software Foundry. 9 * NASA Ames Research Center and Matt Thomas of 3am Software Foundry.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
@@ -730,26 +730,28 @@ extern struct mownerhead mowners; @@ -730,26 +730,28 @@ extern struct mownerhead mowners;
730extern struct mowner unknown_mowners[]; 730extern struct mowner unknown_mowners[];
731extern struct mowner revoked_mowner; 731extern struct mowner revoked_mowner;
732#endif 732#endif
733 733
734MALLOC_DECLARE(M_MBUF); 734MALLOC_DECLARE(M_MBUF);
735MALLOC_DECLARE(M_SONAME); 735MALLOC_DECLARE(M_SONAME);
736 736
737struct mbuf *m_copym(struct mbuf *, int, int, int); 737struct mbuf *m_copym(struct mbuf *, int, int, int);
738struct mbuf *m_copypacket(struct mbuf *, int); 738struct mbuf *m_copypacket(struct mbuf *, int);
739struct mbuf *m_devget(char *, int, int, struct ifnet *); 739struct mbuf *m_devget(char *, int, int, struct ifnet *);
740struct mbuf *m_dup(struct mbuf *, int, int, int); 740struct mbuf *m_dup(struct mbuf *, int, int, int);
741struct mbuf *m_get(int, int); 741struct mbuf *m_get(int, int);
742struct mbuf *m_gethdr(int, int); 742struct mbuf *m_gethdr(int, int);
 743struct mbuf *m_get_n(int, int, size_t, size_t);
 744struct mbuf *m_gethdr_n(int, int, size_t, size_t);
743struct mbuf *m_prepend(struct mbuf *,int, int); 745struct mbuf *m_prepend(struct mbuf *,int, int);
744struct mbuf *m_pulldown(struct mbuf *, int, int, int *); 746struct mbuf *m_pulldown(struct mbuf *, int, int, int *);
745struct mbuf *m_pullup(struct mbuf *, int); 747struct mbuf *m_pullup(struct mbuf *, int);
746struct mbuf *m_copyup(struct mbuf *, int, int); 748struct mbuf *m_copyup(struct mbuf *, int, int);
747struct mbuf *m_split(struct mbuf *,int, int); 749struct mbuf *m_split(struct mbuf *,int, int);
748struct mbuf *m_getptr(struct mbuf *, int, int *); 750struct mbuf *m_getptr(struct mbuf *, int, int *);
749void m_adj(struct mbuf *, int); 751void m_adj(struct mbuf *, int);
750struct mbuf *m_defrag(struct mbuf *, int); 752struct mbuf *m_defrag(struct mbuf *, int);
751int m_apply(struct mbuf *, int, int, 753int m_apply(struct mbuf *, int, int,
752 int (*)(void *, void *, unsigned int), void *); 754 int (*)(void *, void *, unsigned int), void *);
753void m_cat(struct mbuf *,struct mbuf *); 755void m_cat(struct mbuf *,struct mbuf *);
754void m_clget(struct mbuf *, int); 756void m_clget(struct mbuf *, int);
755void m_copyback(struct mbuf *, int, int, const void *); 757void m_copyback(struct mbuf *, int, int, const void *);