[REVIEW/TEST] polling(4) changes

John Baldwin jhb at FreeBSD.org
Fri Sep 30 07:06:07 PDT 2005


On Friday 30 September 2005 08:40 am, Gleb Smirnoff wrote:
>   [please, follow-up on net@ only]
>
>   Colleagues,
>
>   here are some patches for review.
>
>   Problems addressed:
>
>   1) When Giant was removed from polling a problem was introduced. The idle
> poll feature was broken. The idle poll thread can enter polling handler on
> one interface and put to sleep for a long time, until CPU resources found.
> During this time no traffic is received on interface. Well, this is what
> idle thread is supposed to do. Why didn't this happen with Giant? Because
> idle poll entered poll handler holding Giant, and other threads (in
> particular netisr poll) contested on Giant and propagated their priority to
> idle poll. Well, this is a hack, but idle poll significantly improves
> polling performance on an idle box, that's why I won't axe it but try to
> fix it.
>
>   To address the problem we need to use the same technique as before, but
> use poll_mtx instead of Giant. However, this will resurrect LORs, that were
> fixed with Giant removal. The alternative lock path happens, when driver
> decides to deregister from polling itself. The LOR is fixed by further
> changes. See 3).
>
>   2) Drivers indicate their ability to do polling(4) with IFCAP_POLLING
> flag int if_capabilites field. Setting the flag in if_capenable should
> register interface with polling and disable interrupts. However, the
> if_flags is also abused with IFF_POLLING flag. The aim is to remove
> IFF_POLLING flag.
>
>   3) The polling is switched on and off not functionally. That is, when you
> say 'sysctl kern.polling.enable=1' or 'ifconfig fxp0 -polling', the polling
> is switched on/off not immediately but on next tick or next interrupt. This
> non-functional approach leads to a lot of ambiguouties in code, makes it
> harder to understand and maintain. It also exposes race conditions.
>
> The attached patch removes:
>   - IFF_POLLING flag.
>   - Use of if_flags, if_drv_flags, if_capenable from kern_poll.c.
>     All current accesses to these fields are not locked and polling
> shouldn't look there.
>   - poll in trap feature. Sorry, we can't acquire mutexes in trap(). Anyone
>     used it, anyway?
>   - POLL_DEREGISTER command. No hacks. Everything is done functionally via
>     ioctl().
>
> The new world order for driver is the following:
>
>   1) Declare IFCAP_POLLING in if_capabilities on attach. Do not touch
> if_capenable. 2) in ioctl method, in SIOCSIFCAP case the driver should:
> 	- call ether_poll_[de]register
> 	- if no error, set the IFCAP_POLLING flag in if_capenable
> 	- obtain driver lock
> 	- [dis/en]able interrupts
> 	- drop driver lock
>   3) In poll method, check IFF_DRV_RUNNING flag after obtaining driver lock
>   4) In interrupt handler check IFCAP_POLLING flag in if_capenable. If
> present, then return. This is important to protect from spurious
> interrupts. 5) In device detach method, call ether_poll_deregister() before
> obtaining driver lock.

From my limited experience with locking various NIC drivers, I like this 
change.  I think it is much better to tweak the polling state in the ioctl() 
handler rather than in the poll handler.

-- 
John Baldwin <jhb at FreeBSD.org>  <><  http://www.FreeBSD.org/~jhb/
"Power Users Use the Power to Serve"  =  http://www.FreeBSD.org


More information about the freebsd-net mailing list