tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Inter-driver #if dependencies



On Sun, 17 May 2015, Matt Thomas wrote:


On May 17, 2015, at 3:40 PM, Paul Goyette <paul%vps1.whooppee.com@localhost> wrote:

My crusade for modularity has arrived at the pcppi(4) driver, and I've discovered that there are a number of places in the code where a #if is used to determine whether or not some _other_ driver is available to provide certain routines.  For pcppi(4), these dependencies are for the attimer(4) and pckbd(4) drivers.  (While I haven't yet gone searching, I'd be willing to wager that there are other similar examples in other drivers.)

These #if constructs make it very difficult to modularize these drivers.

I'd like to propose the following new kernel mechanism that will allow us to remove these #if dependencies.

1. Extend the struct cfattach to have an additional member, and create
 a new CFATTACH_DECL4_NEW macro to initialize it (and updates to the
 existing CFATTACH_* family to default the value to NULL).

	int	(*ca_callback)(device_t, int, void *);

 (This will require a kernel version bump.)

Ewww.  Gross.

I didn't really like it either, but I couldn't think of another way to reduce the #if spaghetti.

(And I really didn't like the name ca_callback either, but I couldn't think of any better name.)


It might be better to use weak symbols and then fix them up later.

I thought of using weak symbols, but I wasn't really sure how it would work....

If you call a routine via a weak symbol, and the routine/symbol isn't defined, doesn't that just result in a call to "0"? Would the caller need to check first to see if the routine were defined? (ie, have a local pointer variable initialized to the weak-symbol, and code checks to see if the pointer is non-NULL before calling?)

Would the weak-symbol mechanism work in a modular environment, where either driver could be the first to exist? If neither driver is included in the kernel, and there is no hard dependency between the drivers, then you could 'modload a ; modload b' vs 'modload b ; modload a' and it should work the same in either case. So, weak-symbol fix-up would need to work regardless of whether the references are already loaded. (You can't just fix-up things in the module currently being loaded, you have to see if previously-loaded modules have any weak "forward" references, too.)

If the module which provides the "real" definition of the weak symbol gets unloaded, does the symbol "revert" to a weak one? And do any references which may have already been fixed-up get similarly reverted? (ie, the local-pointer-variable would need to get reset back to NULL).

I'm not sure that a "passive" linker-based solution would work in all cases. I don't have any specific examples at hand, but it just "feels" like a more active mechanism might sometimes be needed, where one driver can tell the other "I'm being unloaded, so clean up any state you may have that refers to me and/or abort any in-progress activity."

It seems to me that, if this were only a compile time or static-link time problem, a weak-symbol solution might work / be appropriate. But in a run-time/dynamic-link-unlink situation it "feels" insufficient.


Sorry for not being able to replace "feels" with more specific details and concrete examples.

:)




-------------------------------------------------------------------------
| Paul Goyette     | PGP Key fingerprint:     | E-mail addresses:       |
| (Retired)        | FA29 0E3B 35AF E8AE 6651 | paul at whooppee.com    |
| Kernel Developer | 0786 F758 55DE 53BA 7731 | pgoyette at netbsd.org  |
-------------------------------------------------------------------------


Home | Main Index | Thread Index | Old Index