tech-net archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: if_txtimer API to replace (*if_watchdog)()
> Date: Thu, 23 Jan 2020 22:37:55 -0800
> From: Jason Thorpe <thorpej%me.com@localhost>
>
> There are a 3 basic problems:
>
> 1- if_timer relies on the KERNEL_LOCK.
Agreed.
> 2- if_timer does not have a way to model multiple queues.
Does if_txtimer have a way to model multiple queues? Is it not just
driver-specific logic to handle sc->sc_txq[i].txq_lastsent for each
queue independently like wm(4)?
> 3- There should be one basic way to modeling the transmit watchdog
> timer, rather than N. (In the examples you cited above, N is
> definitely > 1.)
If we just replaced if_slowtimo by an explicit callout in each driver
just like wm_tick, would you still consider that to be >1 model?
> Callouts are a bit more expensive... to arm them or introspect them
> requires taking an additional lock **shared by other callouts** that
> could be a source of lock contention;
The lock is normally the per-CPU lock of the CPU where it was last
scheduled, so that should be pretty cheap unless something is going
seriously wrong with callouts and/or the driver.
> This could make a difference when you're trying to blast out packets
> at 40Gb/s.
Which drivers (a) are for hardware devices that can handle >>1GB/sec,
and (b) use if_watchdog -- i.e., which high-throughput drivers would
take advantage of the callout-based mechanism inside your proposed
if_txtimer?
> Callouts also have a larger memory footprint ... not hugely so, mind
> you, but each one is 10 pointers large; my proposal uses a bit less
> memory than callouts... nearly a wash if you consider the fields
> that can be removed from struct ifnet when the conversion of every
> driver is complete.
If we break the drivers into two classes:
1. Those that currently use if_watchdog.
- Status quo: There already is exactly 1 callout per device.
- With callouts: There would still be exactly 1 callout per device,
but in struct foo_softc instead of struct ifnet.
- With if_txtimer: There would still be exactly 1 callout per
device, but in struct if_txtimer instead of struct ifnet.
2. Those that currently do not use if_watchdog and do their own thing.
- Status quo: There already are (1 + n) callouts per device, where
n is however many the driver allocates to do its own thing.
- With callouts: There would be n callouts per device because we
get rid of if_slowtimo.
- With if_txtimer: There would be n callouts per device because we
get rid of if_slowtimo.
I don't see a difference. Am I missing something?
> Tx transmit timers have no need for precision ... 1 second
> granularity is totally sufficient, and many drivers are already
> using a 1-second tick timer for link maintenance / stats updating;
> my proposal piggy-backs on that. The cost is that you do some work
> once a second.
I don't understand how this makes a difference between just using
callouts directly, and hiding callouts in an API that uses them on
request. Can you elaborate?
> The intent of if_txtimer_callout is to essentially provide a the
> callout-backed "tick" facility to drive if_txtimer to drivers that
> wouldn't otherwise need that facility for their own purposes. It's
> a set of convenience functions to reduce code duplication.
Can you show what code is deduplicated this way?
The diff has +102 -82, even if I ignore the additions in net/if.h and
net/if.c. Some + is to be expected by pushing stuff from struct ifnet
optionally into struct foo_softc, but I read through the patch and I
don't see anything that looks plausibly like deduplication, other than
perhaps the expression in if_txtimer_expired_explicit in wm(4). The
comment and whitespace density seems to be about the same before and
after, so that seems like it's increasing the amount of code _and_ the
API complexity.
> > For example, will any driver call if_txtimer_start
> > without actually knowing up front whether it needs to use the callout?
> > Will any driver call if_txtimer_stop in a code path that would not be
> > adequately served either by if_txtimer_disarm, or by an unconditional
> > if_txtimer_disarm & callout_stop?
>
> The rules are pretty simple:
My questions weren't about the rules for use. My questions were:
1. Will any driver call if_txtimer_start without actually knowing up
front whether it needs to use the callout?
2. Will any driver call if_txtimer_stop in a code path that would not
be adequately served either by if_txtimer_disarm, or by an
unconditional if_txtimer_disarm & callout_stop?
That is, will there be any code paths which meaningfully take
advantage of having a run-time conditional? If yes, can you give an
example? If no, why do we need a replica of the callout API spelled
differently in if_txtimer?
In the diff you showed, the answers to both questions are no: wm(4)
and pcn(4) _know_ they don't use the if_txtimer callout, so they don't
need if_txtimer_start/stop at all; sq(4) _knows_ it uses the
if_txtimer callout, so it could just as well use callout_schedule and
callout_stop instead of if_txtimer_start/stop.
This suggests to me that the if_txtimer API (at least, the version
with optional callouts) is confounding two different purposes and
would make it harder, not easier, to understand the drivers -- it uses
one name, but there are really two disparate usage models.
Home |
Main Index |
Thread Index |
Old Index