Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 26 Feb 2014 11:29:07 +0000 (UTC)
From:      Gleb Smirnoff <glebius@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r262527 - user/glebius/course/09.mbufs
Message-ID:  <201402261129.s1QBT7IC072272@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: glebius
Date: Wed Feb 26 11:29:07 2014
New Revision: 262527
URL: http://svnweb.freebsd.org/changeset/base/262527

Log:
  More on mbufs.

Modified:
  user/glebius/course/09.mbufs/lection.tex

Modified: user/glebius/course/09.mbufs/lection.tex
==============================================================================
--- user/glebius/course/09.mbufs/lection.tex	Wed Feb 26 09:08:25 2014	(r262526)
+++ user/glebius/course/09.mbufs/lection.tex	Wed Feb 26 11:29:07 2014	(r262527)
@@ -19,7 +19,7 @@
 
 \input{../course.tex}
 
-\title{Network Input/Output: mbufs. Mbuf manipulations. Netgraph.}
+\title{Network Input/Output: mbufs}
 
 \begin{document}
 
@@ -258,12 +258,13 @@
 }
 \onslide <2-> {
   \node [name=mextstr, below=1em of empty.south east, anchor=north east,
-	 struct, rectangle split parts=5] {
+	 struct, rectangle split parts=6] {
 	\textbf{struct m\_ext}
-	\nodepart{two}char *ext\_buf
-	\nodepart{three}uint32\_t ext\_size
-	\nodepart{four}uint32\_t ext\_flags
-	\nodepart{five}int (*ext\_free)(...)
+	\nodepart{two}u\_int *ref\_cnt
+	\nodepart{three}char *ext\_buf
+	\nodepart{four}uint32\_t ext\_size
+	\nodepart{five}uint32\_t ext\_flags
+	\nodepart{six}int (*ext\_free)(...)
   };
   \draw (mext.south west) -- (mextstr.north west);
   \draw (mext.south east) -- (mextstr.north east);
@@ -272,7 +273,7 @@
 	 minimum height=3em, text width=.8\paperwidth, align=center]
 	{ \textit{cluster} (2048 bytes) };
 
-  \draw [->,thick] (mextstr.two west)
+  \draw [->,thick] (mextstr.three west)
 	.. controls +(-3,-3) and +(0,2) .. (cluster.north west);
   \draw [->,thick] (mhdrstr.two east)
 	.. controls +(2,-2) and +(0,2) .. (node cs:name=cluster, angle=170);
@@ -282,4 +283,168 @@
 \end{frame}
 
 
+\FootReferences{}{sys/kern/kern\_mbuf.c}
+\begin{frame}
+\frametitle{Allocation of mbufs}
+  \begin{itemize}
+    \item{UMA zones:
+	\begin{itemize}
+	  \item{mbuf (256 bytes) zone}
+	  \item{cluster (2048 bytes) zone}
+\onslide <2-> {
+	  \item{``packet'' zone}
+}
+\onslide <3-> {
+	  \item{PAGE\_SIZEd zone}
+	  \item{Jumbo-sized zone}
+}
+\onslide <4-> {
+	  \item{refcount zone (sizeof(u\_int))}
+}
+	\end{itemize}
+    }
+\onslide <5-> {
+    \item {Statistics can be analyzed with vmstat(8), netstat(1)}
+}
+\onslide <6-> {
+    \item {Usually allocation happens:
+	\begin{itemize}
+	  \item{Driver fills its RX ring}
+	  \item{User data is copied into socket buffer on write(2)}
+	\end{itemize}
+    }
+}
+\onslide <7-> {
+    \item {Layers pass ownership of mbufs to each other}
+}
+  \end{itemize}
+\end{frame}
+
+
+\FootReferences{mbuf(9)}{sys/sys/mbuf.h, sys/kern/kern\_mbuf.c}
+\begin{frame}
+\frametitle{Allocation APIs}
+  \begin{itemize}
+    \item{Explicit allocation:
+	\begin{itemize}
+    	  \item{m\_get(how, type) - allocate 256 byte mbuf}
+    	  \item{m\_gethdr(how, type) - allocate M\_PKTHDR mbuf}
+    	  \item{m\_getcl(how, type, flags) - allocate ``packet'': mbuf+cluster}
+\onslide <2-> {
+    	  \item{m\_get2(size, how, type, flags) - allocate minimum sized buffer}
+    	  \item{m\_getm(size, how, type, flags) - allocate chain of buffers}
+}
+	\end{itemize}
+    }
+\onslide <3-> {
+    \item{Implicit allocation:
+	\begin{itemize}
+	  \item{m\_uiotombuf(uio, ...) - copy uio(9) to allocated chain}
+	  \item{m\_devget(char *, ...) - copy buffer to allocated chain}
+	  \item{m\_copym(mbuf, ...) - copy mbuf(9) chain to new one}
+	\end{itemize}
+    }
+}
+\onslide <4-> {
+    \item{Freeing:
+	\begin{itemize}
+	  \item{m\_free(m) - free this mbuf and return its m\_next}
+	  \item{m\_freem(m) - free entire chain}
+	\end{itemize}
+    }
+}
+  \end{itemize}
+\end{frame}
+
+
+\FootReferences{mbuf(9)}{sys/sys/mbuf.h, sys/kern/uipc\_mbuf.c}
+\begin{frame}
+\frametitle{Dereferencing, prepending and aligning mbufs}
+  \begin{itemize}
+    \item{Dereferencing:
+	\begin{itemize}
+	  \item{protoheader = mtod(m, cast) -- cast m\_data to a header}
+	  \item{Must check m\_len!}
+	  \item{m = m\_prepend(m, len) --
+		guarantee m\_data contiguity of len bytes}
+	\end{itemize}
+    }
+\onslide <2-> {
+    \item{Prepending:
+	\begin{itemize}
+	  \item{M\_PREPEND(m, len, how) -- macro to prepend len before m\_data}
+	  \item{m\_prepend(m, len, how) -- hard part of M\_PREPEND}
+	\end{itemize}
+    }
+}
+\onslide <3-> {
+    \item{Aligning:
+	\begin{itemize}
+	  \item{M\_ALIGN(m, len), MH\_ALIGN(m, len) -- set m\_data to len bytes
+		at end of data area}
+	  \item{m\_align(m, len) -- same for any type of mbuf}
+	\end{itemize}
+    }
+}
+  \end{itemize}
+\end{frame}
+
+
+\FootReferences{}{sys/netinet/ip\_input.c}
+\begin{frame}[fragile]
+\frametitle{Example: dereferencing mbufs}
+\begin{beamercolorbox}[rounded=true,shadow=true]{source}
+\lstset{language=C}
+\scriptsize\begin{lstlisting}
+void
+ip_input(struct mbuf *m)
+{
+        struct ip *ip;
+
+        if (m->m_pkthdr.len < sizeof(struct ip))
+                goto tooshort;
+
+        if (m->m_len < sizeof (struct ip) &&
+            (m = m_pullup(m, sizeof (struct ip))) == NULL) {
+                IPSTAT_INC(ips_toosmall);
+                return;
+        }
+        ip = mtod(m, struct ip *);
+
+        if (ip->ip_v != IPVERSION) {
+                IPSTAT_INC(ips_badvers);
+                goto bad;
+        }
+\end{lstlisting}
+\end{beamercolorbox}
+\end{frame}
+
+
+\FootReferences{}{sys/net/if\_ethersubr.c}
+\begin{frame}[fragile]
+\frametitle{Example: prepending header}
+\begin{beamercolorbox}[rounded=true,shadow=true]{source}
+\lstset{language=C}
+\scriptsize\begin{lstlisting}
+int
+ether_output(struct ifnet *ifp, struct mbuf *m,
+        const struct sockaddr *dst, struct route *ro)
+{
+        struct ether_header *eh;
+
+        M_PREPEND(m, ETHER_HDR_LEN, M_NOWAIT);
+        if (m == NULL)
+                senderr(ENOBUFS);
+        eh = mtod(m, struct ether_header *);
+        memcpy(&eh->ether_type, &type,
+            sizeof(eh->ether_type));
+        memcpy(eh->ether_dhost, edst,
+            sizeof(eh->ether_dhost));
+        memcpy(eh->ether_shost, IF_LLADDR(ifp),
+            sizeof(eh->ether_shost));
+\end{lstlisting}
+\end{beamercolorbox}
+\end{frame}
+
+
 \end{document}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201402261129.s1QBT7IC072272>