Page MenuHomeFreeBSD

DrvAPI: Extend driver KPI with more accessors
ClosedPublic

Authored by jhibbits on Dec 9 2022, 8:57 PM.
Tags
None
Referenced Files
Unknown Object (File)
Tue, Dec 10, 7:21 AM
Unknown Object (File)
Wed, Dec 4, 5:56 PM
Unknown Object (File)
Thu, Nov 28, 10:08 PM
Unknown Object (File)
Thu, Nov 21, 4:19 PM
Unknown Object (File)
Wed, Nov 20, 9:02 AM
Unknown Object (File)
Tue, Nov 19, 4:36 PM
Unknown Object (File)
Mon, Nov 18, 6:24 AM
Unknown Object (File)
Mon, Nov 18, 5:35 AM

Details

Summary

Add the following accessors to hide some more netstack details:

  • if_get/setcapabilities2 and *bits analogue
  • if_setdname
  • if_getxname
  • if_transmit - wrapper for call to ifp->if_transmit()
  • This required changing the existing if_transmit to

if_transmit_default, since that's its purpose.

  • if_getalloctype
  • if_getindex
  • if_foreach_addr_type - Like if_foreach_lladdr() but for any address family type. Used by some drivers to iterate over all AF_INET addresses.
  • if_init() - wrapper for ifp->if_init() call
  • if_setinputfn
  • if_setsndtagallocfn
  • if_togglehwassist

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped
Build Status
Buildable 48761
Build 45647: arc lint + arc unit

Event Timeline

Next step would be to move all the accessors into net/if.h, and make if_var.h private to sys/net (netstack).

First of all, I fully support the ifnet KPI approach and love to see this (and the other relevant) reviews landed. Thank you for doing this!
Some questions -

  1. When some action happens (like, a user sets the MTU), then (a) driver-specific internal structures and HW state are updated, (b) actual ifp datastructed gets updated, and (c) network-stack-specific staff is triggered (eventhandler etc).

In the current KPI most of the if_set() functions do just (b), but there are examples of functions doing all 3 items (if_setlladdr()). Any thoughts on differentiating between these two classes?

  1. Any thoughts on locking for setters?
  1. Any plans to update ifnet(9)? :-)
sys/net/if.c
4245

Do we really want to expose these two capabilities fields as is?

Could we do per-bit-index interface instead, w/o exposing any underlying storage details?

It would have a nice property of not dealing with setcapabilities3, 4 and so on.

4335

There is already a widely-used if_name() macro. I'd vote for having either if_name() or if_getname(), preferring the former.

4364

It is probably worth considering having const if_t in all getters.

4491

Does it need to have the return code?

4617

Do we want to enter the epoch instead of enforcing the epoch?
To call this function safely, one has to either be in the epoch already or hold an ifp reference.
Personally, I'd prefer to reduce the number of cases when one needs to acquire/free references for the objects.

4828

Nit: worth having input_cb signature separately.

First of all, I fully support the ifnet KPI approach and love to see this (and the other relevant) reviews landed. Thank you for doing this!

Thanks for the review!

Some questions -

  1. When some action happens (like, a user sets the MTU), then (a) driver-specific internal structures and HW state are updated, (b) actual ifp datastructed gets updated, and (c) network-stack-specific staff is triggered (eventhandler etc).

In the current KPI most of the if_set() functions do just (b), but there are examples of functions doing all 3 items (if_setlladdr()). Any thoughts on differentiating between these two classes?

I'm mixed on this. I think it requires further thinking of how drivers and the stack interact, and how other things interact with the stack. if_setlladdr() for instance looks like it needs to be hardware and stack oriented, to keep everything in sync. Unless we make the KPI a "set" and "commit" style. Thoughts on that direction?

  1. Any thoughts on locking for setters?

Maybe for the next iteration of things? Right now just doing the naive approach to get the KPI in place and get drivers ported over.

  1. Any plans to update ifnet(9)? :-)

Definitely need to do that. Thanks for reminding me.

sys/net/if.c
4245

I agree with you, but there are many places that already do if_setcapabilitiesbit(), so expect a bitmask word. Maybe make it accept a bitset instead?

4335

Not sure how I missed it, but yeah if_name() is better than if_getname(). if_getname() would imply that you're getting an immutable object, which is obviously not the case.

4364

I like this idea.

4491

Probably not. All the other setters do have return values, probably for other stacks that could return an error (hypothetically).

4828

Good idea, I was following existing practice, but those existing should be fixed as well.

sys/net/if.c
4617

Maybe? I'm not sure here. This is analogous to the if_foreach_lladdr() and if_foreach_llmaddr() functions. Should those be updated as well?

Address feedback from @melifaro.

  • Switch to if_name() from if_getxname() (makes more sense)
  • Add function typedefs for members, to be used in accessors.

>> Some questions -

  1. When some action happens (like, a user sets the MTU), then (a) driver-specific internal structures and HW state are updated, (b) actual ifp datastructed gets updated, and (c) network-stack-specific staff is triggered (eventhandler etc).

In the current KPI most of the if_set() functions do just (b), but there are examples of functions doing all 3 items (if_setlladdr()). Any thoughts on differentiating between these two classes?

I'm mixed on this. I think it requires further thinking of how drivers and the stack interact, and how other things interact with the stack. if_setlladdr() for instance looks like it needs to be hardware and stack oriented, to keep everything in sync. Unless we make the KPI a "set" and "commit" style. Thoughts on that direction?

It certanly requires thinking. Also, there are also interaction inside the current stack that should be considered w.r.t KPI changes. Specifically, I mean the change notifications that needs to be propagated to the other parts of kernel and/or userland programs.
Set&commit may bring some benefits. I don't see any way that wouldn' add significant complexity both to the underlying implementation and the KPI users. I don't think it's worth the effort.

  1. Any thoughts on locking for setters?

Maybe for the next iteration of things? Right now just doing the naive approach to get the KPI in place and get drivers ported over.

Sure, I don't expect it to be the scope of this change - more curious abouth the thoughts on the general approach.

  1. Any plans to update ifnet(9)? :-)

Definitely need to do that. Thanks for reminding me.

That's great!

sys/net/if.c
424

Nit: if_init_idxtable() ?

4245

I'd try to have per-bit manipulation as the core KPI, with maybe the compat wrapper handling lower 32/64 bits.
Alternatively, maybe we can have a macro that accepts a static array of bit indexes ?
e.g.

static const uint8_t cap_bits[] = { IFCAP_RXCSUM_BIT, IFCAP_TOE6, IFCAP_TOE4 };
IF_SETCAPABILITIES(ifp, cap_bits)

?

4335

Nit: should we return const char * ?

4364

Awesome! If we're on the same page, probably worth doing it from day 1? What do you think?

4617

We can probably leave it as is for now and discuss epoch stuff separately.

jhibbits added inline comments.
sys/net/if.c
4245

kib in D32551 stated capabilities2 is for the 'nvlist' caps, so maybe it's better to leave setcapabilities/setcapabilitiesbit as-is, and add the new KPI for all new capabilities, to be used by the nvlist caps?

4335

Sure. Needed to finesse some other code to make it work.

4364

Consider it done in the next diff.

jhibbits marked 2 inline comments as done.

Address more feedback from @melifaro.

Change if_setcapababilities2, etc to if_setcapabilities_list(), with a single-capability option of if_setcapability().

I apologise for the belated response.
Thank you for addressing the comments!
The only remaining thing I'd prefer to discuss a bit more is the setcaps2 thing. I'd rather prefer to move these bits to a dedicated review. It would be easier to iron out KPIs around that (I can come up with the one if you're okay with it).
The rest I'm totally fine with - and I'd love to see that landed.

sys/net/if.c
4245

Sorry for being picky on that.
I'm going to export all capabilities to userland via netlink interface info, in a bitarray parameter,

Netlink userland interface allows to get, set, append or remove certain bits from the capabilties.
Personally, from the stack standpoint the good KPI can be the following:

bool if_checkcap(ifp, cap_bit)
int if_setcapbit(ifp, cap_bit)
int if_clearcapbit(ifp, cap_bit)
void if_getcaparray(ifp, array_p, array_sz)
int if_setcaps(ifp, array_p, array_sz, bool clear)
This revision is now accepted and ready to land.Dec 20 2022, 10:36 AM
sys/net/if.c
4245

Only mlx5 currently uses if_capabilities2 from what I can tell, so it's not a big sticking point yet. I'll rip it out for further discussion and review.