Packet loss every 30.999 seconds

Bruce Evans brde at
Wed Dec 19 11:41:12 PST 2007

On Wed, 19 Dec 2007, David G Lawrence wrote:

>> The patch should work fine.  IIRC, it yields voluntarily so that other
>> things can run.  I committed a similar hack for uiomove().  It was
>   It patches the bottom of the loop, which is only reached if the vnode
> is dirty. So it will only help if there are thousands of dirty vnodes.
> While that condition can certainly happen, it isn't the case that I'm
> particularly interested in.


When it reaches the bottom of the loop, it will probably block on i/o
sometimes, so that the problem is smaller anyway.

>> CPUs, everything except interrupts has to wait for these syscalls.  Now
>> the main problem is to figure out why PREEMPTION doesn't work.  I'm
>> not working on this directly since I'm running ~5.2 where nearly-full
>> kernel preemption doesn't work due to Giant locking.
>   I don't understand how PREEMPTION is supposed to work (I mean
> to any significant detail), so I can't really comment on that.

Me neither, but I will comment anyway :-).  I think PREEMPTION should
even preempt kernel threads in favor of (higher priority of course)
user threads that are in the kernel, but doesn't do this now.  Even
interrupt threads should have dynamic priorities so that when they
become too hoggish they can be preempted even by user threads subject
to the this priority rule.  This is further from happening.

ffs_sync() can hold the mountpoint lock for a long time.  That gives
problems preempting it.  To move your fix to the top of the loop, I
think you just need to drop the mountpoint lock every few hundred
iterations while yielding.  This would help for PREEMPTION too.  Dropping
the lock must be safe because it is already done while flushing.

Hmm, the loop is nicely obfuscated and pessimized in current (see
rev.1.234).  The fast (modulo no cache misses) path used to be just a
TAILQ_NEXT() to reach the next vnode, but now unnecessarily joins the
slow path at MNT_VNODE_FOREACH(), and MNT_VNODE_FOREACH() hides a
function call.


More information about the freebsd-net mailing list