svn commit: r358040 - in projects/nfs-over-tls/sys: kern sys
Rick Macklem
rmacklem at FreeBSD.org
Mon Feb 17 20:09:08 UTC 2020
Author: rmacklem
Date: Mon Feb 17 20:09:06 2020
New Revision: 358040
URL: https://svnweb.freebsd.org/changeset/base/358040
Log:
Add two functions to kern_mbuf.c used by the RPC-over-TLS to
copy a list of regular mbuf(s) to a list of ext_pgs ones.
If these are not considered generic enough, they can easily
be moved to the krpc sources and renamed.
Modified:
projects/nfs-over-tls/sys/kern/kern_mbuf.c
projects/nfs-over-tls/sys/sys/mbuf.h
Modified: projects/nfs-over-tls/sys/kern/kern_mbuf.c
==============================================================================
--- projects/nfs-over-tls/sys/kern/kern_mbuf.c Mon Feb 17 20:02:14 2020 (r358039)
+++ projects/nfs-over-tls/sys/kern/kern_mbuf.c Mon Feb 17 20:09:06 2020 (r358040)
@@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_extern.h>
#include <vm/vm_kern.h>
#include <vm/vm_page.h>
+#include <vm/vm_pageout.h>
#include <vm/vm_map.h>
#include <vm/uma.h>
#include <vm/uma_dbg.h>
@@ -1592,4 +1593,107 @@ m_snd_tag_destroy(struct m_snd_tag *mst)
ifp->if_snd_tag_free(mst);
if_rele(ifp);
counter_u64_add(snd_tag_count, -1);
+}
+
+/*
+ * Allocate an mbuf with anonymous external pages.
+ */
+struct mbuf *
+mb_alloc_ext_plus_pages(int len, int how, bool pkthdr, m_ext_free_t ext_free)
+{
+ struct mbuf *m;
+ vm_page_t pg;
+ int i, npgs;
+
+ m = mb_alloc_ext_pgs(how, pkthdr, ext_free);
+ if (m == NULL)
+ return (NULL);
+ m->m_ext.ext_pgs->flags |= MBUF_PEXT_FLAG_ANON;
+ npgs = howmany(len, PAGE_SIZE);
+ for (i = 0; i < npgs; i++) {
+ do {
+ pg = vm_page_alloc(NULL, 0, VM_ALLOC_NORMAL |
+ VM_ALLOC_NOOBJ | VM_ALLOC_NODUMP | VM_ALLOC_WIRED);
+ if (pg == NULL) {
+ if (how == M_NOWAIT) {
+ m->m_ext.ext_pgs->npgs = i;
+ m_free(m);
+ return (NULL);
+ }
+ vm_wait(NULL);
+ }
+ } while (pg == NULL);
+ m->m_ext.ext_pgs->pa[i] = VM_PAGE_TO_PHYS(pg);
+ }
+ m->m_ext.ext_pgs->npgs = npgs;
+ return (m);
+}
+
+/*
+ * Copy the data in the mbuf chain to a chain of mbufs with external pages.
+ * len is the length of data in the input mbuf chain.
+ * mlen is the maximum number of bytes put into each ext_page mbuf.
+ */
+struct mbuf *
+mb_copym_ext_pgs(struct mbuf *mp, int len, int mlen, int how, bool pkthdr,
+ m_ext_free_t ext_free, struct mbuf **mlast)
+{
+ struct mbuf *m, *mout = NULL;
+ char *pgpos = NULL, *mbpos;
+ int i = 0, mblen, mbufsiz, pglen, xfer;
+
+ if (len == 0)
+ return (NULL);
+ m = NULL;
+ pglen = mblen = 0;
+ do {
+ if (pglen == 0) {
+ if (m == NULL || ++i == m->m_ext.ext_pgs->npgs) {
+ mbufsiz = min(mlen, len);
+ if (m == NULL) {
+ m = mout = mb_alloc_ext_plus_pages(
+ mbufsiz, how, pkthdr, ext_free);
+ if (m == NULL)
+ return (m);
+ if (pkthdr)
+ m->m_pkthdr.len = len;
+ } else {
+ m->m_ext.ext_pgs->last_pg_len =
+ PAGE_SIZE;
+ m->m_next = mb_alloc_ext_plus_pages(
+ mbufsiz, how, false, ext_free);
+ m = m->m_next;
+ if (m == NULL) {
+ m_freem(mout);
+ return (m);
+ }
+ }
+ i = 0;
+ }
+ pgpos = (char *)(void *)
+ PHYS_TO_DMAP(m->m_ext.ext_pgs->pa[i]);
+ pglen = PAGE_SIZE;
+ }
+ while (mblen == 0) {
+ if (mp == NULL) {
+ m_freem(mout);
+ return (NULL);
+ }
+ mbpos = mtod(mp, char *);
+ mblen = mp->m_len;
+ mp = mp->m_next;
+ }
+ xfer = min(mblen, pglen);
+ bcopy(mbpos, pgpos, xfer);
+ pgpos += xfer;
+ mbpos += xfer;
+ pglen -= xfer;
+ mblen -= xfer;
+ len -= xfer;
+ m->m_len += xfer;
+ } while (len > 0);
+ m->m_ext.ext_pgs->last_pg_len = PAGE_SIZE - pglen;
+ if (mlast != NULL)
+ *mlast = m;
+ return (mout);
}
Modified: projects/nfs-over-tls/sys/sys/mbuf.h
==============================================================================
--- projects/nfs-over-tls/sys/sys/mbuf.h Mon Feb 17 20:02:14 2020 (r358039)
+++ projects/nfs-over-tls/sys/sys/mbuf.h Mon Feb 17 20:09:06 2020 (r358040)
@@ -700,6 +700,9 @@ void mb_dupcl(struct mbuf *, struct mbuf *);
void mb_free_ext(struct mbuf *);
void mb_free_mext_pgs(struct mbuf *);
struct mbuf *mb_alloc_ext_pgs(int, bool, m_ext_free_t);
+struct mbuf *mb_alloc_ext_plus_pages(int, int, bool, m_ext_free_t);
+struct mbuf *mb_copym_ext_pgs(struct mbuf *, int, int, int, bool,
+ m_ext_free_t, struct mbuf **);
int mb_unmapped_compress(struct mbuf *m);
struct mbuf *mb_unmapped_to_ext(struct mbuf *m);
void mb_free_notready(struct mbuf *m, int count);
More information about the svn-src-projects
mailing list