Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 10 Oct 2005 18:50:32 +0000 (GMT)
From:      wpaul@FreeBSD.ORG (Bill Paul)
To:        wpaul@FreeBSD.org (Bill Paul)
Cc:        cvs-src@FreeBSD.org, src-committers@FreeBSD.org, cvs-all@FreeBSD.org
Subject:   Re: cvs commit: src/sys/compat/ndis kern_ndis.c kern_windrv.c ndis_var.h ntoskrnl_var.h subr_hal.c subr_ndis.c subr_ntoskrnl
Message-ID:  <20051010185032.5385516A420@hub.freebsd.org>
In-Reply-To: <200510101646.j9AGkdEE031063@repoman.freebsd.org> from Bill Paul at "Oct 10, 2005 04:46:39 pm"

next in thread | previous in thread | raw e-mail | index | archive | help
> wpaul       2005-10-10 16:46:39 UTC
> 
>   FreeBSD src repository
> 
>   Modified files:
>     sys/compat/ndis      kern_ndis.c kern_windrv.c ndis_var.h 
>                          ntoskrnl_var.h subr_hal.c subr_ndis.c 
>                          subr_ntoskrnl.c winx32_wrap.S 
>     sys/dev/if_ndis      if_ndis.c if_ndisvar.h 
>   Log:
>   This commit makes a big round of updates and fixes many, many things.
>   

[chop]
 
Oh wait, I forgot something.
 
BSD networking uses what I call the "stack loans to driver" model
for packet buffer handling. That is, there's one OS-wide pool of
mbufs and cluster buffers, and drivers borrow buffers from that pool,
fill them with incoming packets, then hand them back.
 
But Windows (and, coincidentally, VxWorks) implicitly uses the "driver
loans to stack" model, where it's the drivers that create buffer pools
(NdisAllocatePacketPool(), NdisAllocateBufferPool()) and loan buffers
to the stack, which eventually has to release them all.
 
I originally wrote ndis_rxeof() to do zero-copy, where I just allocate
an mbuf and attach the NDIS_PACKET to it, in order to avoid allocating
a whole mbuf/cluster tuple and copying the data. Unfortunately, due to
the conflicting buffer handling models, there's a possible deadlock:
you can't call MiniportHalt() until all the packet buffers loaned
out by the driver have been returned. If you call MiniportHalt() too
early, the driver might block the halt until the last buffer is
returned. I think Windows makes sure all packets have been cancelled
before NDIS calls MiniportHalt(). Thing is, I can't think of a
good way to implement this on FreeBSD (short of keeping track of
each and every packet that gets sent into the stack and tsleep()ing
until they're all returned).
 
So for now, ndis_rxeof() has been modified to just copy the packet
data and return the NDIS_PACKET to the driver immediately. For the
most part, I don't think anyone's going to notice the difference anyway.

-Bill

--
=============================================================================
-Bill Paul            (510) 749-2329 | Senior Engineer, Master of Unix-Fu
                 wpaul@windriver.com | Wind River Systems
=============================================================================
              <adamw> you're just BEGGING to face the moose
=============================================================================



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