Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 20 Dec 94 10:11:24 MST
From:      terry@cs.weber.edu (Terry Lambert)
To:        ugen@netvision.net.il (Ugen J.S.Antsilevich)
Cc:        terry@cs.weber.edu (Terry Lambert), hackers@freebsd.org
Subject:   Re: hi!
Message-ID:  <9412201711.AA28823@cs.weber.edu>
In-Reply-To: <Chameleon.941220103340.ugen@ugen.NetManage.co.il>; from "Ugen J.S.Antsilevich" at Dec 20, 94 10:22 am

next in thread | previous in thread | raw e-mail | index | archive | help
>  So first of all unrelated to lkm question: what the hell had
> happaned to freefall???!!! Do we at least have list of
> all those who are in mail lists so may be we can put this lists in 
> some other place temporarily?? I just don't feel so good without my 200
> morning emails :^)

I'm sure there are backups, after all WC CDROM relies on it to provide
masters for one of its products.

But the machine itself has been down hard for over a day now... I have
no guess as to why.

>  Now to lkm..
> This is nice and interesting facility which probably will not get
> any use in FreeBSD:) ppl somewhy prefer to compile everything they 
> se into kernel-unix philosofy you know:))
>  1) I'v seen in manual on lkm that somwhere in /usr/share/lkm wonderplace
> there should be an example code on them...Well..the directory does not
> exists..And the lkm's which are in system mostly consist of standart
> kernel code and have no one single comment regarding how do you 
> write lkm...Suggestions where can i find it?:)

I haven't looked at the newest stuff, which I assume was derived from
NetBSD -- the beta code I donated, modified by Chris Demetrioux.  He added
man pages and several other things.

I don't know if the examples I gave (a printer driver, a system call, and
the /kern FS) are applicable any more.  I doubt it completely for the
printer driver (the interrupt mechanism has changed since then) and I
also doubt it for the /kern FS (the file system has *drastically*
changed).

I modeled a lot of what I did on the Sun mechanism.  It's definitely
command-line compatible with SunOS 4.1.3.

The internals are somewhat different.

Loading an LKM requires that you modify a pointer or table in the kernel
to point at the code in the LKM (after it is loaded).  Generally, this
is accomplished by either manually pointing some value at yourself, or
by calling a wrapper routine to do it for you based on your module type.

For system calls, the wrapper is passed a system call slot to allocate
or a -1, plus a complete 'sysent' structure for the system call to be
inserted.  In the case of a -1, the functions in the system call table
are compared to a known function address (this used to be lkmnosys()),
and the first entry of this type is replaced with the new entry provided.

At the same time, the LKM system itself keeps track of the memory allocated
during the load process, and which slot, etc was allocated to ensure that
a call to the right LKM code can unload the code again (by restoring the
previous table contents, then freeing up the memory allocated to contain
the module.

For device drivers, the entry passed is a cdevsw[] or bdevsw[] entry, and
the same search takes place.  The device switch mechanism has been altered
to not allow calls to nulled entries, and nulled entries are what the
loader looks for, similar to looking for system calls.

Initially, there was no way to specify both a block and a character device
simultaneously.  I don't know if this has changed.  My method of handling
this case was to load one driver as one of the devices, and a stub driver
that made calls to the other driver as a dependent module of the first
driver.

>  2) I'v understood that there are standart type of lkm's..So to write such 
> type of lkm i don't need to do anything special just compile it as module
> and it will run well?? (Device driver and stuff like that)

There is a load, unload, and query routine.  There is also an entry point
or init routine for the module itself.  The entry point acts as a mux for
calss to the load/unload/query by way of indirect reference.  That is,
the entry point registers the known functions with the lkm system as well
for use in device load (including refusal to load if probe fails), unload
(unhooking irq/drq/memory), and query (the module status function that
returns common module information and an integer of data about the module.
For system calls, the data is the system call slot entry (the offset into
the system call table).  For devices, it's the major or minor.  For
"generic" modules (modules that do their own kernel table/pointer hacking
to install themselves), it's whatever the user wants to return.

>  3) Most important: i am trying to move my firewall inside loadable module.
> It is probably going to be misc. module so there is thing about it:
>   * Can i some way overlap some function in kernel with my one??
>     ( when firewall is up and running i make some calls inside
>       ipintr or ip_forward for example which does not present when firewall
>       don't..so i need to load not firewall functions only but change code
>       in ipintr & Co)

Yes, if it is a run-time resolved function.  What that means is that the
function can't be statically referenced, it must be referenced via a
function pointer.  The only things you can change, really, are the contents
of kernel data areas.  If one of those data areas happens to be the function
pointer that is dereferenced to access that function, then you can replace
it.

In terms of protocols in general, I'd like to se a structure containing
function pointers for all functions in each protocol, with a common set of
functions defined to handled "protocolness" as an idea.  Then a table of
protocols which is a table of pointers to these structures.

Ideally, you want a module to be able to load an entirely new protocol
by adding to the table, or to replace pieces of a protocol by going to
a specific protocol slot in the table, dereferencing it to get the
structure, and replacing the desired function pointer(s) in the table.

It's also quite possible that a loaded module might hack its own table.
For instance, a module IPX loads that depends on XNS (another module).
It adds it's protocol structure to the table, then changes the contents
of its own protocol structure to point to the XNS routines (XNS and IPX
are very similar).

>   * If i can't how can i define kernel in some place to call another
>     function when module loaded?

DECLARATION:
int	(*replaceable_func)() = default_func();


REFERENCE:
	...
	(*replaceable_func)( p1, p2, p3 ...);
	...


MODULE LOADER:
	...
	replaceable_func = new_func();
	...

>  4) Memory question..If i made some malloc's while module running and unload
>     module then malloc's are not freed, arn't they?

No; this would constitute "resource tracking" of module resource usage.

I would think there are two types of memory resources that could be
allocated during a modules lifetime (excluding the actual memory taken
by the module itself).

The first type is memory that you'd want "cleaned up".  This is trackable.

The second is memory that *under*no*circumstances is allowed to be
cleaned up.  This memory is not directly trackable.  You'll just have
to take the hit on it, or put in a lot of effort to track it indirectly.

In the first category, you have per device structures, per file system
vnode pools, and other memory for which there is not a use after the
module has been inactivated.  Note the use of the word "Inactivated".
A module can be told to unload, and it can determine that it is "busy".
Generally this is because it can't recover some resources.  For a file
system, this might mean that the file system type is still mounted and
therefore the code is in use.  For a device, that it's open.  For a
system call, that it has been entered but not exited.  This is all the
extra housekeeping you must do in a module to ensure that the kernel
isn't actively using it when it "goes away" (a panic condition!).  To
resource track this type of information, you would have to change the
kernel memory model to include the concept of discrete pools that are
freed when the last pool reference disappears.  Then you would allocate
a pool on load (reference increment), and decrement in unload (with the
reference count going to 0 triggering deallocation).  Then you would
use pool aware allocation and deallocation routines for the memory in
the modules -- passing the pool id along with the allocation/deallocation
requests (ie: pool_kmem_alloc, etc.).


In the second category, you have additions to kernel memory stores.
These are generic additions, so you can't get rid of them, since you
can't guarantee that your module is the only user.  Consider an ethernet
protocol buffer.  The buffers are allocated from a common set of all of
the available buffers by the particular protocol, but they are replaced
in the set of available buffers by the ethernet driver after they have
been transmitted.

The ethernet driver has no idea who allocated the buffers.  Certainly,
you could tag each buffer, but this would greatly increase the buffer
overhead if you wanted to keep each buffer start page aligned at the
same time, or vastly increase processing overhead otherwise.  So the
ethernet driver returns them to a common pool.

It's likely that if you are going to add additional protocol support to
an existing kernel, you would want to grow the set of available buffers.
But in so doing, you add them to the common pool.  Thus a particular
buffer for your NetBEUI module could be in use by someone elses IP
module, etc..  So you can't simply free them up.

What you *can* do is tag and coelesce the space itself.  Then on buffer
replacement, a bufer in a tagged hunk would not be replaced into the
common pool, and the hunk reference would be decremented by one.  When
a tagged hunk's reference goes to 0, you deallocate the hunk.

In practice, I think a lot of this code would have to be in place before
LKMs would be generally useful for protocol modules, but for developement,
it wouldn't really matter -- except that you have to be prepared to do
your own resource tracking.

> Ok..that's mostly all..when you'll have free time answer :)
> Thanx!

I haven't gotten anything from the list recently either, with freefall down,
so I have a bit more time than I used to.

Hope this is helpful.


					Terry Lambert
					terry@cs.weber.edu
---
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?9412201711.AA28823>