On 12/12/18(Wed) 12:03, David Gwynne wrote:
> with the previous if_ethersubr.c diff, this allows etherip(4) to output
> directly to the network stack.
What do you mean with "directly"?
To my understanding ip{,6}_etherip_output() call ip{,6}_send() to enqueue
packets.
> direct output relies on the interface using priq, since hfsc uses the
> ifq machinery to work. priq implies you dont want to delay packets, so
> it lets etherip push the packet straight through.
So "direct output" means skip the queue(s)?
So are we heading towards a design where ifq_enqueue(9) is going to be
bypassed for pseudo-drivers unless people use HFSC? If that's the case
I'm afraid that code path will rot.
> i dont think the ifq stuff is slow, but it does allow the stack to
> concurrently send packets with etherip without having to create an ifq
> per cpu. it does rely on per cpu counters, but theyre relatively small.
I don't understand how it allows the stack to concurrently send packets.
All packets seems to be serialized in a single task when ip{,6}_send()
is called.
> the other advantage is it stops ether_output recursing in the etherip
> path. this helps profiling, but that is a fairly niche benefit so maybe
> just focus on the concurrency.
I don't understand. How is ether_output() recursing?
> ok?
I'm a bit sad about where this is going. Because the design you adopted
will forces us to modify all pseudo-drivers. Apart the fact that you're
now breaking etherip(4) into bridge(4) /!\, I believe we can do better.
We had this design:
STACK DRIVER
ether_output() -> if_enqueue() -> ifq_enqueue() + ifq_start() | drv_start()
`. |
`--> bridge_output() |
The problem that you want to solve, if I'm not mistaken, is to remove
the useless stack/driver separation for pseudo-drivers. In other words
stop queueing & delaying packets. This only makes sense for "physical"
nics where mbufs are put into DMA buckets, right?
In that case I'd suggest modifying if_enqueue() or ifq_enqueue() to treat
IFXF_CLONED devices as special if they are not using HSFC.
In other words I suggest you only need to modify what happens *after*
if_enqueue(), the driver part or actual drv_start(). Why about having
a generic:
if (ifp->if_enqueue != NULL && (ifq_is_priq(&ifp->if_snd)) {
counters_pkt(ifp->if_counters, ifc_opackets, ifc_obytes,
m->m_pkthdr.len);
ifp->if_enqueue(ifp, m);
return (0);
}
I'm not sure if we can do better than introducing a new per-ifp method.
This is what you called etherip_send() in your diff. But I believe the
vlan(4) example is more interesting because if calls if_enqueue(9) directly!
So I disagree with the changes requiring a custom `if_output' and with the
bypassing of if_enqueue(). That said I could be completely mistaken :)