Date: Thu, 12 Oct 1995 19:14:00 -0700 (MST) From: Terry Lambert <terry@lambert.org> To: julian@ref.tfs.com (Julian Elischer) Cc: terry@lambert.org, jhay@mikom.csir.co.za, hackers@FreeBSD.ORG Subject: Re: IPX now available Message-ID: <199510130214.TAA16568@phaeton.artisoft.com> In-Reply-To: <199510121946.MAA05651@ref.tfs.com> from "Julian Elischer" at Oct 12, 95 12:46:21 pm
next in thread | previous in thread | raw e-mail | index | archive | help
> > We want a registration mechanism for LLC's, another for protocol > > families, etc.. > > I agree, but there are getting to be too many registration mechaninsms > we need to stand back.. > take a deep breath, and think about which registration mechanisms are > needed, and what we can do to make thismore standard and generic. > > at the moment we have: > a linker_set for networking protocol domains (DOMAIN_SET) > a linker set for arbitrary modules (SYSINIT) > a registration protocol for SCSI devices (not a linker set but could be) > a registration for devices (syscontrol stuff) > a registration for devices (devfs stuff) > (I guess we should have a registration for devices and interrupts/dma) > a linker set for filesystems > a linker set for net ISRs > a linker set for PCI support > a linker set for exec modules > a way to add a new devsw entry for yourself > > what have I missed? > > I guess I'm addressing this to a wider audience.. > what do we want to have here? OK, I just sent off a message a bit ago to Serge Vakulenko (vak@cronyx.msk.su) about a message he sent me about making the LKM interface more generic. The gist of this is that he wants to work on putting simple linker code into the kernel, and I very much agree with him. I think that there is an issue here that is not being addressed, which is the fact that the SYSINIT() mechanism is already sufficiently generic, as long as you can get a deinitialization routine registered for callback at unload time, and as long as you can cause the LKM load procedure to call the SYSINT's in the linker sets via a mechanism similar to init_main.c. The linker set for protocol domains is, in fact, broken. Try adding IPX. The linker set for file systems is also broken, mostly because the callback system in vfs_inti.c is broken (inherited broken code from 4.4BSD-Lite). OK. Start with the general. What is a loadable kernel component? A loadable kernel component is code that when loaded sets itself up as if it had always been there, and if unloaded, removes itself as if it had never been there. It turns out the the SYSINIT() mechanism, which can call a routine with data without caring what routine or data is provided is sufficiently generic to provide this. What else must a loadable kernel component do? It needs to find out if it is unnecessary (probe). It needs to allow multiple instances of itself, with different configuration data (attach). It needs to allow an instance of itself to be destroyed (detach). It needs to release any resources (including callback registrations) that it caused to exist at load time when it is unloaded. What's left? Programmer convenience functions. Currently, the LKM system implements convenience functions on a per module class basis. A Loadable module may, in fact, modify any writeable kernel structure at load time. It could replace exiting system calss, or could even overwrite a function preable with a jump to another function. Convenince functions are the API's which a module (loaded or static) may consume. Stay with me here. Examples of convenience functions: vfs_add_fs vfs_remove_fs dev_add_char (just dev_add?) dev_remove_char (just dev_remove?) dev_add_block (just dev_add?) dev_remove_block (just dev_remove?) net_add_family net_remove_family net_add_llc net_remove_llc net_add_interface (should be generalized as a device) net_remove_interface (should be generalized as a device) etc. In point of fact, these are *not* clutter. These are functions which allow the sharing of code that would have to be duplicated per device in an already existing framework. They also allow the ability to guard common data structures to protect them, which would otherwise have to be done on a per module basis. So let's take an instance: a device. In the devfs, it's arguable that, since major and minor numbers are now menaingless, the vonode instance is itself the device. This greatly simplifies the issues involved. So what must a device do (independent of whether it is statically or dynamically loaded)? 1) It must allocate any global structures it requires before any routines it exports are called. 2) It must non-destructively probe for all locations it is possible for the device to exist. 3) It must attach all instances of the device in the system for which it provides services. 4) It must detach an instance of the device if access to the device is revoked (PCMCIA, etc). 5) It must non-destructively reprobe for a new instance (PCMCIA, etc.) 6) It must reattach a reprobe instance 7) It must deallocate global structures before it is rendered unusable, either through administrative fiat or through unload. Probe includes: a) determination of IRQ(s) used by a single device instance before attach. b) determination of DRQ(s) used by a single device instance before attach. c) determination of I/O address range(s) used by a single device instance before attach. d) determination of Mapped memory region(s) used by a single device instance before attach. Attach includes: a) allocation of per instance memory b) vectoring of IRQ's c) storage of per instance configuration data from the probe d) relocation of the device based on allowable values as determined by the probe in order to avoid conflicts. e) Potentially using power management controls to make the device available. f) export of device nodes Detach includes: a) destruction of device nodes b) unvectoring IRQ's c) resetting the device to cold reboot state d) Potentially using power management controls to take the device off line. d) freeing of per instance memory Meta operations for probe: a) Confict resoution, including determining optimal device parameter relocation, if necessary ("Plug N Play"). b) designation of a conflict vector for a successfully probed device. c) Ordering of operations in the case of multiple busses so that the non-relocatable devices are given their preferences. Meta operations for attach: a) Lock down of location vector on successful attach. Meta operations for detach: a) Freeing of location vector resources for reuse The assumptions present in the above: 1) Runtime triggering of potentially destructive probes on addition of new hardware. It is unrealistics to assum all probes can be made to be non-destructive. 2) Logging of probes (per Win95) to allow destructive proves to be used to create a static device configuration table using kernel level file I/O. I think it's quite possible to make the load/link of devices generic to the point that there is no difference between an "ld -r"'ed object to be statically linked into a kernel and one to be dynamically loaded at runtime. I also think that it would be a good idea to force parining of block and non block devices for interface where that is applicable. In specific, I think that the device should be exported to two locations in the devfs hierarchy without additional effort. I think that functional interfaces, both to guard global data structures and to abstract otherwise duplicate code should be defined for all major kernel components. It should be noted that the "functional interface interface" could be one such loadable interface definition, meaning that one could load the common initialization/deinitialization code for file systems, load a file system, and unload the common code. I think it is also time to consider discontiguous kernel memory for things like low, medium, and high persistance objects to avoid the fragmentation of the kernel address space that going to such heavy use of loading interfaces would probably entail. Terry Lambert terry@lambert.org --- Any opinions in this posting are my own and not those of my present or previous employers.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199510130214.TAA16568>