MCPcopy Create free account
hub / github.com/F-Stack/f-stack / m_unshare

Function m_unshare

freebsd/kern/uipc_mbuf.c:1918–2034  ·  view source on GitHub ↗

* Create a writable copy of the mbuf chain. While doing this * we compact the chain with a goal of producing a chain with * at most two mbufs. The second mbuf in this chain is likely * to be a cluster. The primary purpose of this work is to create * a writable packet for encryption, compression, etc. The * secondary goal is to linearize the data so the data can be * passed to crypto hard

Source from the content-addressed store, hash-verified

1916 * passed to crypto hardware in the most efficient manner possible.
1917 */
1918struct mbuf *
1919m_unshare(struct mbuf *m0, int how)
1920{
1921 struct mbuf *m, *mprev;
1922 struct mbuf *n, *mfirst, *mlast;
1923 int len, off;
1924
1925 mprev = NULL;
1926 for (m = m0; m != NULL; m = mprev->m_next) {
1927 /*
1928 * Regular mbufs are ignored unless there's a cluster
1929 * in front of it that we can use to coalesce. We do
1930 * the latter mainly so later clusters can be coalesced
1931 * also w/o having to handle them specially (i.e. convert
1932 * mbuf+cluster -> cluster). This optimization is heavily
1933 * influenced by the assumption that we're running over
1934 * Ethernet where MCLBYTES is large enough that the max
1935 * packet size will permit lots of coalescing into a
1936 * single cluster. This in turn permits efficient
1937 * crypto operations, especially when using hardware.
1938 */
1939 if ((m->m_flags & M_EXT) == 0) {
1940 if (mprev && (mprev->m_flags & M_EXT) &&
1941 m->m_len <= M_TRAILINGSPACE(mprev)) {
1942 /* XXX: this ignores mbuf types */
1943 memcpy(mtod(mprev, caddr_t) + mprev->m_len,
1944 mtod(m, caddr_t), m->m_len);
1945 mprev->m_len += m->m_len;
1946 mprev->m_next = m->m_next; /* unlink from chain */
1947 m_free(m); /* reclaim mbuf */
1948 } else {
1949 mprev = m;
1950 }
1951 continue;
1952 }
1953 /*
1954 * Writable mbufs are left alone (for now).
1955 */
1956 if (M_WRITABLE(m)) {
1957 mprev = m;
1958 continue;
1959 }
1960
1961 /*
1962 * Not writable, replace with a copy or coalesce with
1963 * the previous mbuf if possible (since we have to copy
1964 * it anyway, we try to reduce the number of mbufs and
1965 * clusters so that future work is easier).
1966 */
1967 KASSERT(m->m_flags & M_EXT, ("m_flags 0x%x", m->m_flags));
1968 /* NB: we only coalesce into a cluster or larger */
1969 if (mprev != NULL && (mprev->m_flags & M_EXT) &&
1970 m->m_len <= M_TRAILINGSPACE(mprev)) {
1971 /* XXX: this ignores mbuf types */
1972 memcpy(mtod(mprev, caddr_t) + mprev->m_len,
1973 mtod(m, caddr_t), m->m_len);
1974 mprev->m_len += m->m_len;
1975 mprev->m_next = m->m_next; /* unlink from chain */

Callers 12

ieee80211_mbuf_adjustFunction · 0.85
ng_patch_rcvdataFunction · 0.85
ng_pred1_compressFunction · 0.85
ng_pred1_decompressFunction · 0.85
ng_deflate_compressFunction · 0.85
ng_deflate_decompressFunction · 0.85
ng_mppc_compressFunction · 0.85
ng_mppc_decompressFunction · 0.85
ng_checksum_rcvdataFunction · 0.85
ipcomp_outputFunction · 0.85
ah_outputFunction · 0.85
esp_outputFunction · 0.85

Calls 6

m_move_pkthdrFunction · 0.85
minFunction · 0.85
m_freemFunction · 0.70
memcpyFunction · 0.50
m_freeFunction · 0.50
m_getclFunction · 0.50

Tested by

no test coverage detected