Source-Changes-D archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: CVS commit: src/sys/kern
hey, thanks for all the fixes!
I'm trying to import a driver (while being very new to
networking/driver stuff), and updating to -current fixed an issue I've
had, most likely from this commit.
Now my ported driver is close to working :-)
On Sat, Apr 28, 2018 at 08:16:15AM +0000, Maxime Villard wrote:
> Module Name: src
> Committed By: maxv
> Date: Sat Apr 28 08:16:15 UTC 2018
>
> Modified Files:
> src/sys/kern: uipc_mbuf.c
>
> Log Message:
> Modify m_defrag, so that it never frees the first mbuf of the chain. While
> here use the given 'flags' argument, and not M_DONTWAIT.
>
> We have a problem with several drivers: they poll an mbuf chain from their
> queues and call m_defrag on them, but m_defrag could update the mbuf
> pointer, so the mbuf in the queue is no longer valid. It is not easy to
> fix each driver, because doing pop+push will reorder the queue, and we
> don't really want that to happen.
>
> This problem was independently spotted by me, Kengo, Masanobu, and other
> people too it seems (perhaps PR/53218).
>
> Now m_defrag leaves the first mbuf in place, and compresses the chain
> only starting from the second mbuf in the chain.
>
> It is important not to compress the first mbuf with hacks, because the
> storage of this first mbuf may be shared with other mbufs.
>
>
> To generate a diff of this commit:
> cvs rdiff -u -r1.210 -r1.211 src/sys/kern/uipc_mbuf.c
>
> Please note that diffs are not public domain; they are subject to the
> copyright notices on the relevant files.
>
> Modified files:
>
> Index: src/sys/kern/uipc_mbuf.c
> diff -u src/sys/kern/uipc_mbuf.c:1.210 src/sys/kern/uipc_mbuf.c:1.211
> --- src/sys/kern/uipc_mbuf.c:1.210 Fri Apr 27 19:06:48 2018
> +++ src/sys/kern/uipc_mbuf.c Sat Apr 28 08:16:15 2018
> @@ -1,4 +1,4 @@
> -/* $NetBSD: uipc_mbuf.c,v 1.210 2018/04/27 19:06:48 maxv Exp $ */
> +/* $NetBSD: uipc_mbuf.c,v 1.211 2018/04/28 08:16:15 maxv Exp $ */
>
> /*
> * Copyright (c) 1999, 2001 The NetBSD Foundation, Inc.
> @@ -62,7 +62,7 @@
> */
>
> #include <sys/cdefs.h>
> -__KERNEL_RCSID(0, "$NetBSD: uipc_mbuf.c,v 1.210 2018/04/27 19:06:48 maxv Exp $");
> +__KERNEL_RCSID(0, "$NetBSD: uipc_mbuf.c,v 1.211 2018/04/28 08:16:15 maxv Exp $");
>
> #ifdef _KERNEL_OPT
> #include "opt_mbuftrace.h"
> @@ -1475,27 +1475,32 @@ enobufs:
> }
>
> /*
> - * Copy the mbuf chain to a new mbuf chain that is as short as possible.
> - * Return the new mbuf chain on success, NULL on failure. On success,
> - * free the old mbuf chain.
> + * Compress the mbuf chain. Return the new mbuf chain on success, NULL on
> + * failure. The first mbuf is preserved, and on success the pointer returned
> + * is the same as the one passed.
> */
> struct mbuf *
> m_defrag(struct mbuf *mold, int flags)
> {
> struct mbuf *m0, *mn, *n;
> - size_t sz = mold->m_pkthdr.len;
> + int sz;
>
> KASSERT((mold->m_flags & M_PKTHDR) != 0);
>
> - m0 = m_gethdr(flags, MT_DATA);
> + if (mold->m_next == NULL)
> + return mold;
> +
> + m0 = m_get(flags, MT_DATA);
> if (m0 == NULL)
> return NULL;
> - M_COPY_PKTHDR(m0, mold);
> mn = m0;
>
> + sz = mold->m_pkthdr.len - mold->m_len;
> + KASSERT(sz >= 0);
> +
> do {
> - if (sz > MHLEN) {
> - MCLGET(mn, M_DONTWAIT);
> + if (sz > MLEN) {
> + MCLGET(mn, flags);
> if ((mn->m_flags & M_EXT) == 0) {
> m_freem(m0);
> return NULL;
> @@ -1511,7 +1516,7 @@ m_defrag(struct mbuf *mold, int flags)
>
> if (sz > 0) {
> /* need more mbufs */
> - n = m_get(M_NOWAIT, MT_DATA);
> + n = m_get(flags, MT_DATA);
> if (n == NULL) {
> m_freem(m0);
> return NULL;
> @@ -1522,9 +1527,10 @@ m_defrag(struct mbuf *mold, int flags)
> }
> } while (sz > 0);
>
> - m_freem(mold);
> + m_freem(mold->m_next);
> + mold->m_next = m0;
>
> - return m0;
> + return mold;
> }
>
> void
>
Home |
Main Index |
Thread Index |
Old Index