Skip to contentSkip to conversation

Where did vm_operations_struct->unmap in 2.4.0 go?

DISCUSSION Allen Unueco 8 participants 19 messages Jan 10, 2001 – Jan 14, 2001

lore
Share & tools
lore
#0 lore raw

Sometime around test10 or test11 unmap left vm_operations_struct. The comment implies its there but it's gone. Where did it go?

How do I get a call back for a page unmap?

I ran into this while hacking the Nvidia kernel driver to work with 2.4.0. I got the driver working but it's not 100%

Also where did get_module_symbol() and put_module_symbol() go?

-Allen
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#2 lore raw
In reply to Allen Unueco
Quoted 4 lines · Allen Unueco

Sometime around test10 or test11 unmap left vm_operations_struct. The comment implies its there but it's gone. Where did it go?

Quoted 8 lines

How do I get a call back for a page unmap?

I ran into this while hacking the Nvidia kernel driver to work with 2.4.0. I got the driver working but it's not 100%

Also where did get_module_symbol() and put_module_symbol() go?

-Allen

Patches for the NVIDIA binary X drivers following all these kernel changes can be gotten from IRC server irc.openprojects.net, channel #nvidia. Or from http://ex.shafted.com.au/nvidia/

--
- Antony Suter ([email protected]) "ExWired" openpgp:71ADFC87
- "...to condense fact from the vapor of nuance."
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#3 lore raw
Quoted 9 lines · Antony Suter
Quoted 4 lines · Allen Unueco

I ran into this while hacking the Nvidia kernel driver to work with 2.4.0. I got the driver working but it's not 100%

Also where did get_module_symbol() and put_module_symbol() go?

Patches for the NVIDIA binary X drivers following all these kernel changes can be gotten from IRC server irc.openprojects.net, channel #nvidia. Or from http://ex.shafted.com.au/nvidia/

And what a pile of crud those patches are!! Instead of using the clean replacement interface for get_module_symbol, nvidia/patch-2.4.0-PR hard codes the old get_module_symbol algorithm as inline code.

This patch violates the modules interface by accessing modules.c internal data. It still suffers from all the problems that get_module_symbol had. Because it is hard coded as inline code instead of a common function, will be much harder to fix when it breaks.

Whoever coded that patch should be taken out and shot, hung, drawn and quartered then forced to write COBOL for the rest of their natural life.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#4 lore raw
Quoted 4 lines · [email protected] said:

And what a pile of crud those patches are!! Instead of using the
clean replacement interface for get_module_symbol, nvidia/ patch-2.4.0-PR hard codes the old get_module_symbol algorithm as inline code.

Taking away get_module_symbol() and providing a replacement which has link order problems wasn't really very sensible.

You've changed a lookup in a static table built at compile time to a lookup in a dynamic table which has to be built in the right order at runtime.

It's too late to do the sensible thing and deprecate the old version rather than having a 'flag day'. But can we at least fix the link order crap?

struct static_inter_module_entry {
	const char *im_name;
	const void *userdata;
};

#define inter_module_register_static(x,y) \

 static struct static_inter_module_entry __ime_##x \
	__attribute__((unused,__section__(".intermodule")) \
	= { #x, y };

.. and the obvious for looking in that table in inter_module_get().

--
dwmw2

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#5 lore raw
Quoted 11 lines · David Woodhouse

Taking away get_module_symbol() and providing a replacement which has link order problems wasn't really very sensible.

It's too late to do the sensible thing and deprecate the old version rather than having a 'flag day'. But can we at least fix the link order crap?

struct static_inter_module_entry {
	const char *im_name;
	const void *userdata;
};
Quoted 6 lines

#define inter_module_register_static(x,y) \

static struct static_inter_module_entry __ime_##x \
	__attribute__((unused,__section__(".intermodule")) \
	= { #x, y };

.. and the obvious for looking in that table in inter_module_get().

If object X registers data for object Y to use then X _must_ initialise before Y. It does not matter whether the registration method is static or dynamic, the initialisation order must be observed.

Q. With your suggested static method, what happens when Y initialises
before X, calls inter_module_get, retrieves X's static data and starts to use it before X has initialised?
A. Oops!

The whole point of registration methods is that the owner of the data decides when they are ready to provide the service. Ensuring that code is initialised in the correct order, with providers starting before consumers, is a fact of life.

I dislike the method that the kernel uses to control initialisation order, but that is an entirely separate problem from inter_module_xxx. What we really want at startup is a correct initialisation order. What we have is the order that objects are selected in a Makefile which maps to the link order of objects in vmlinux which maps to the listed order of init routines in section .init.text which maps to initialisation order. The mechanism is three layers away from the problem and it is difficult to understand for many people.

It would be much nicer to define ordering sets. Code in driver foo needs the code in driver bar to initialise first. cfi_probe cannot initialise until cfi_cmdset_0001 and cfi_cmdset_0002 have initialised. Declare it that way so it is clear what is going on and why, instead of being implied by the Makefile order via three layers of indirection. Then let the kernel build system do whatever it takes to honour the documented initialisation order.

The problem is, Linus likes the current method.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#6 lore raw
Quoted 4 lines · [email protected] said:

Q. With your suggested static method, what happens when Y initialises
before X, calls inter_module_get, retrieves X's static data and starts to use it before X has initialised?
A. Oops!

No. You'd explicitly only use the static registration when object X doesn't _need_ initialisation, which is the case for my code.

As it is, I've had to add completely now init routines for modules which didn't have them before, and all those init routines do is inter_module_register() and pray that they're called in time.

Quoted 4 lines · [email protected] said:

The whole point of registration methods is that the owner of the data
decides when they are ready to provide the service. Ensuring that code is initialised in the correct order, with providers starting before consumers, is a fact of life.

I have decided when I'm ready to provide the service. At compile time. Ensuring that the code is initialised in the correct order is not a fact of life. It's an artifact of the limited functionality of the new setup.

Quoted 6 lines · [email protected] said:

It would be much nicer to define ordering sets. Code in driver foo needs the code in driver bar to initialise first. cfi_probe cannot initialise until cfi_cmdset_0001 and cfi_cmdset_0002 have initialised. Declare it that way so it is clear what is going on and why, instead of being implied by the Makefile order via three layers of indirection.

For cases where the code really does need initialisation, that is true. It should be done properly rather than just implicitly ordered by the Makefile. But in this case, the command set drivers don't need initialisation. They just provide a function for use by the generic CFI init code. They don't _need_ to initialise themselves beforehand.

The dynamic registration has introduced this ordering dependency when previously there was none.

Quoted 1 line

The problem is, Linus likes the current method.

Then he either hasn't considered this particular case, or he's wrong. It happens. I'm not suggesting that we change it drastically, only that we add the option of static (compile-time) registration for those entries which require it.

Actually, I'd rather do this with weak symbols. Something along the lines of...

extern cfi_cmdset_fn_t cfi_cmdset_0001 __attribute__((weak)); extern cfi_cmdset_fn_t cfi_cmdset_0002 __attribute__((weak));

...

if (cfi_cmdset_0001 && chip_is_type_1())

	return cfi_cmdset_0001(args...);
 if (cfi_cmdset_0002 && chip_is_type_2())
	return cfi_cmdset_0002(args...);

return cfi_cmdset_load_module(args...)

Unfortunately, I couldn't get it to work reliably on anything but x86.

--
dwmw2

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#7 lore raw
Quoted 3 lines · David Woodhouse

I'm not suggesting that we change it drastically, only that we add the option of static (compile-time) registration for those entries which require it.

So you want two services, one static for code that does not do any initialisation and one dynamic for code that does do initialisation. Can you imagine the fun when somebody adds startup code to a routine that was using static registration? Oh dear, I added init code so I have to remember to change from static to dynamic registration, and that affects the link order so now I have to tweak the Makefile. Thanks, but no thanks!

Stick to one method that works for all routines, dynamic registration. If that imposes the occasional need for a couple of extra calls in some routines and for people to think about initialisation order right from the start then so be it, it is a small price to pay for long term stability and ease of maintenance.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#8 lore raw
Quoted 5 lines

Stick to one method that works for all routines, dynamic registration. If that imposes the occasional need for a couple of extra calls in some routines and for people to think about initialisation order right from the start then so be it, it is a small price to pay for long term stability and ease of maintenance.

What happens when we get a loop in init order because of binding and other init order conflicts?
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#9 lore raw
Quoted 8 lines · Alan Cox
Quoted 5 lines

Stick to one method that works for all routines, dynamic registration. If that imposes the occasional need for a couple of extra calls in some routines and for people to think about initialisation order right from the start then so be it, it is a small price to pay for long term stability and ease of maintenance.

What happens when we get a loop in init order because of binding and other init order conflicts?

The kernel does not support circular dependencies between providers and consumers. It does not matter whether they are built into vmlinux or loaded as modules, there can be no loops in the directed graph of dependencies. It just does not make sense.

A while ago there was accidentally a loop between two ppp related modules, each needed a routine in the other module. modprobe would not load them. Even if it could have loaded them, it would have been impossible to unload, both modules would have had a use count on the other. The fix was to remove the incorrect loop, it was a programming error.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#10 lore raw
In reply to Alan Cox
Quoted 7 lines · Keith Owens
Quoted 2 lines

What happens when we get a loop in init order because of binding and other init order conflicts?

The kernel does not support circular dependencies between providers and consumers. It does not matter whether they are built into vmlinux or loaded as modules, there can be no loops in the directed graph of dependencies. It just does not make sense.

So why don't we use sth. like depmod for these issues and get the link order automagically (like we get module load order)?

Keith: Perhaps you could explain, why this is impossible.

Regards

Ingo Oeser

Signature · 6 lines
10.+11.03.2001 - 3. Chemnitzer LinuxTag <http://www.tu-chemnitz.de/linux/tag>
         <<<<<<<<<<<<       come and join the fun       >>>>>>>>>>>>
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/
#11 lore raw
Quoted 2 lines · Ingo Oeser

So why don't we use sth. like depmod for these issues and get the link order automagically (like we get module load order)?

depmod handles dependencies on symbols. Module Y needs a symbol from module X so modprobe must load X before Y. This is a link/load problem which depmod handles fairly well.

The initialisation order is a dependency on actions, not on symbols. Code F cannot start until code E has initialised so execute E before F. This should have *NOTHING* to do with link order, but it is implemented as a side effect of link ordering which confuses people.

People need to realise that the problem is initialisation order, nothing more, nothing less. You have to determine and document the startup requirements for your code. Only you know what the startup pre-requisites for your code are, there is no way for another program to determine this from the source. Document your startup requirements, implement according to the documentation and your problems go away.

Initialisation order is not the problem, the implementation is the problem. The method currently used to control initialisation order sucks. It is better than the original method (lots of conditional calls in main.c) but it still sucks.

* Initialisation order is set by the order of structures in section .initcall.init.
* The order of the structures in .initcall.init is set by the order that objects are linked into vmlinux.
* The link order for vmlinux is derived from a combination of line order within a Makefile plus an overriding directory link order from the top level Makefile and parent Makefiles.
* Because order is a side effect of adding a line to a Makefile, the order requirements are rarely documented.

It is no wonder that people have problems getting the initialisation order correct.

I want to completely remove this multi layered method for setting initialisation order and go back to basics. I want the programmer to say "initialise E and F after G, H and I". The kernel build system works out the directed graph of initialisation order then controls the execution of startup code to satisfy this graph.

That still means controlling link order to achieve the required result. But with my approach the complexity would be handled by kbuild based on explicit rules which are documented in the local Makefile, instead of the complexity being handled by programmer via implicit rules scattered over several layers of Makefiles.

A typical graph would have scsi disk depends on scsi host adaptor group which depends on pci. Within the scsi host adaptor group you might need to initialise one driver before another, so just declare the few inter-driver dependencies. kbuild would automatically initialise pci then the scsi host adaptors (in the correct order) then scsi disk.

Most of the objects have fairly simple execution dependencies, e.g. all file systems depend on core fs code having already executed. There are no dependencies between most file systems so most file systems could initialise in any order[1] which means they could be linked in any order within the file system group.

I am ready and willing to code this method, it would make kbuild a lot easier to code, as well as making future maintainence a lot easier. Linus refuses to accept this approach. He insists that kernel coders explicitly specify the link order for everything, via Makefile order[2]. As long as Linus insists on kernel coders explicitly controlling the entire link order, we are stuck with the current method. I have tried to change his mind without success.

[1] vfat is one obvious exception, it needs dos first. Also the first few built in file systems must execute in a defined order because that in turn controls the probe order for mount. But this order should be explicitly declared, not as a side effect of the line order in fs/Makefile.

[2] http://www.mail-archive.com/[email protected]/msg10520.html

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#12 lore raw
Quoted 3 lines · Keith Owens

People need to realise that the problem is initialisation order, nothing more, nothing less. You have to determine and document the startup requirements for your code.

This is true. But I'd also agree with the implication which you probably didn't mean to make there - that initialisation order is a problem. :)

Where an init ordering is required, it must be documented and the Makefiles set up accordingly. But I believe that we should also try to avoid requiring such ordering where possible, too.

Quoted 2 lines

It is no wonder that people have problems getting the initialisation order correct.

True. And while that situation continues, I desire to avoid the issue completely by not having any dependencies on init order.

Quoted 5 lines

I want to completely remove this multi layered method for setting initialisation order and go back to basics. I want the programmer to say "initialise E and F after G, H and I". The kernel build system works out the directed graph of initialisation order then controls the execution of startup code to satisfy this graph.

But the fewer such constraints there are, the better. We don't want everyone starting to impose unnecessary link order restrictions instead of thinking about the code a little more and just eliminating them completely.

Quoted 2 lines

A typical graph would have scsi disk depends on scsi host adaptor group which depends on pci.

No. sd will happily take over any existing devices when as and when they arrive. It doesn't have to be loaded last. Likewise, in theory at least, host adaptor drivers using the new PCI driver code would respond correctly to the PCI code being initialised (and calling their ->probe routine) later, although that doesn't happen now.

Why have these dependencies where they're not necessary?

Quoted 3 lines

Within the scsi host adaptor group you might need to initialise one driver before another, so just declare the few inter-driver dependencies.

And there are few. And there should _remain_ few. We shouldn't start imposing link order restrictions on other code which doesn't really need it.

Quoted 2 lines

Most of the objects have fairly simple execution dependencies, e.g. all file systems depend on core fs code having already executed.

Er... Why? They call register_filesystem() which uses a lock which is staticly initialised. Don't order stuff for the sake of it. If there are filesystems which _do_ require the VFS to be initialised first, those filesystems can be marked as such. I'm not aware of any.

Quoted 5 lines

[1] vfat is one obvious exception, it needs dos first. Also the first few built in file systems must execute in a defined order because that in turn controls the probe order for mount. But this order should be explicitly declared, not as a side effect of the line order in fs/Makefile.

If the fat_inode_hashtable were staticly initialised, that one wouldn't be necessary either. But unfortunately that would be quite ugly.

I don't want to get involved in the link order stuff. I would very much like to avoid having such dependencies. All I want is weak symbols. I want to call a function directly if it's present, and if not I want to attempt to load its module. Without having my probe module have a hard dependency on _all_ the submodules it may decide to ask for.

get_module_symbol() did that for me, and was perfectly acceptable. I needed to use EXPORT_SYMBOL_NOVERS to export the functions for the individual command sets. Big deal.

inter_module_get() almost does that for me, but it imposes link order dependencies, which I want to avoid because I think in this case they're not necessary. All I want is a way to staticly add entries to the inter_module_xxx tables at compile time, because I _have_ done the analysis, and I'm saying that's when they should be made available.

Alternatively, show me how to get weak symbols actually working on all architectures, and I'll forget the whole thing and be happy.

Signature · 7 lines
dwmw2


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/
#13 lore raw
Quoted 9 lines · David Woodhouse
Quoted 2 lines · Keith Owens

A typical graph would have scsi disk depends on scsi host adaptor group which depends on pci.

No. sd will happily take over any existing devices when as and when they arrive. It doesn't have to be loaded last. Likewise, in theory at least, host adaptor drivers using the new PCI driver code would respond correctly to the PCI code being initialised (and calling their ->probe routine) later, although that doesn't happen now.

You just proved my point. It is extremely difficult to deduce the required initialisation order by reading an undocumented Makefile where the init order is implemented as a side effect of selection order. The existing method implies link order when none is required.

Quoted 7 lines
Quoted 2 lines

Most of the objects have fairly simple execution dependencies, e.g. all file systems depend on core fs code having already executed.

Er... Why? They call register_filesystem() which uses a lock which is staticly initialised. Don't order stuff for the sake of it. If there are filesystems which _do_ require the VFS to be initialised first, those filesystems can be marked as such. I'm not aware of any.

I was using scsi and fs as examples, no need to pick holes in the examples. But ...

fs/buffer.c:module_init(bdflush_init)
fs/pipe.c:module_init(init_pipe_fs)
fs/fcntl.c:module_init(fasync_init)
fs/locks.c:module_init(filelock_init)
fs/dnotify.c:module_init(dnotify_init)

I'm no filesystem expert but it appears that some of those core initialisation routines must be executed before most filesystems can start. In particular, filelock_init() must be executed before any filesystem that supports locks is initialised.

Quoted 3 lines

All I want is a way to staticly add entries to the inter_module_xxx tables at compile time, because I _have_ done the analysis, and I'm saying that's when they should be made available.

Firstly inter_module_xxx is only used by that very small subset of code where there are no constraints on whether the caller and callee can be in kernel, in modules or a mixture _and_ some of the objects are optional. It is a special case because most code handles this problem through CONFIG options. If X needs (Y, Z) and X is built into the kernel then (Y, Z) must also be built into the kernel. If Y or Z are optional then control the calls to those functions with CONFIG options. Almost all of the kernel handles it properly though CONFIG, so inter_module_xxx is already a process to handle a few special cases.

Secondly you want static inter_module_xxx tables for a small subset of these special cases, where the source has no other initialisation code. This is piling special cases on special cases. Adding static inter_module_xxx tables requires

* changes to linux/modules.h to define the new table format and
* changes to vmlinux.lds for _every_ architecture to bring all the static tables together in vmlinux and
* new initialisation code in module.c to read and load all the static tables at boot time and
* extra code in modutils to find any static tables in modules and
* an extension to struct modules to let modutils pass information about the static tables to the kernel and
* the kernel code will only work with an upgraded modutils.

That is a lot of work for a very few special cases. OTOH, you could just swap the order of 3 lines in drivers/mtd/Makefile. Guess which alternative I am going for?

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#14 lore raw
Quoted 4 lines · [email protected] said:

You just proved my point. It is extremely difficult to deduce the
required initialisation order by reading an undocumented Makefile where the init order is implemented as a side effect of selection order. The existing method implies link order when none is required.

I agree entirely. But you're confusing the debate on how to satisfy init order dependencies with my desire to avoid them altogether (for certain situations).

Quoted 4 lines · [email protected] said:

I'm no filesystem expert but it appears that some of those core initialisation routines must be executed before most filesystems can start. In particular, filelock_init() must be executed before any filesystem that supports locks is initialised.

No, before any filesystem that supports locks is _mounted_. Big difference. But I'm picking holes in your examples again. I accept that in some cases it is necessary, but I still think it's best to avoid it where possible.

Quoted 9 lines · [email protected] said:

Firstly inter_module_xxx is only used by that very small subset of code where there are no constraints on whether the caller and callee can be in kernel, in modules or a mixture _and_ some of the objects are optional. It is a special case because most code handles this problem through CONFIG options. If X needs (Y, Z) and X is built into the kernel then (Y, Z) must also be built into the kernel. If Y or Z are optional then control the calls to those functions with CONFIG options. Almost all of the kernel handles it properly though CONFIG, so inter_module_xxx is already a process to handle a few special cases.

'properly through CONFIG'? I thought you agreed that doing it through preprocessor options was ugly, and that it was preferable to get rid of such things and deal with the presence or absence of such code cleanly through some mechanism with similar semantics to inter_module_get(). The 'special case' code to which you refer is in fact the first set of such code to attempt to deal with this properly rather than just giving up and hacking it with preprocessor options.

Stepping back a moment and considering it, what we actually appear to be doing is trying to reinvent weak symbols, as far as I can tell.

Quoted 4 lines · [email protected] said:

Secondly you want static inter_module_xxx tables for a small subset
of these special cases, where the source has no other initialisation code. This is piling special cases on special cases. Adding static inter_module_xxx tables requires

I want the registration method not to impose init order restrictions where previously there were none. Where the previous code already had init order ugliness, it's not so much of a problem. But replacing the safe get_module_symbol() with the unsafe inter_module_get() just because the AGP author forgot to use EXPORT_SYMBOL_NOVERS to export the symbols doesn't really strike me as being useful.

The only real difference between the two, other than the module symbol mangling, appears to be that inter_module_get() looks stuff up in a dynamic table which is made at runtime, where get_module_symbol() looks it up in a static table which is made at compile (or module load) time. That was a backward step, and wasn't necessary.

If you object to having both the runtime inter_module_register() and the compile-time one, then ditch the dynamic one. Both current users of inter_module_xxx would be able to use the static version.

But to be honest, I'd settle for ditching the whole blinkin' lot and getting weak symbols working right, if I could.

--
dwmw2

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#15 lore raw
In reply to Ingo Oeser
Quoted 5 lines · Keith Owens

I want to completely remove this multi layered method for setting initialisation order and go back to basics. I want the programmer to say "initialise E and F after G, H and I". The kernel build system works out the directed graph of initialisation order then controls the execution of startup code to satisfy this graph.

I don't doubt you will come up with a workable solution at build time. However, working out a valid graph at execution time is trivial and efficient, given a list of precedence relations of the kind you're suggesting. In fact you don't even have to work out the graph before starting the initialization, it's also trivial to keep a count of unsatisfied initialization conditions at the beginning of each initialization sequence and block until the count goes to zero. (In essence, evaluate a priority sort on the fly.)

--
Daniel
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#16 lore raw
Quoted 7 lines · Daniel Phillips
Quoted 5 lines · Keith Owens

I want to completely remove this multi layered method for setting initialisation order and go back to basics. I want the programmer to say "initialise E and F after G, H and I". The kernel build system works out the directed graph of initialisation order then controls the execution of startup code to satisfy this graph.

Quoted 8 lines

I don't doubt you will come up with a workable solution at build time. However, working out a valid graph at execution time is trivial and efficient, given a list of precedence relations of the kind you're suggesting. In fact you don't even have to work out the graph before starting the initialization, it's also trivial to keep a count of unsatisfied initialization conditions at the beginning of each initialization sequence and block until the count goes to zero. (In essence, evaluate a priority sort on the fly.)

It is safer to evaluate the graph at link time in case somebody mistakenly codes a dependency loop, that is an abort case. Finding that you have a loop at load time and aborting the kernel is a little too drastic for my tastes.

In any case it is academic. Linus insists on link order being explicitly and completely specified by the programmer and he likes the link order being implied by Makefile order. So there is no point in working on a better system.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#17 lore raw

[email protected] (Keith Owens) wrote on 12.01.01 in <[email protected]>:

Quoted 23 lines
Quoted 7 lines · Daniel Phillips
Quoted 5 lines · Keith Owens

I want to completely remove this multi layered method for setting initialisation order and go back to basics. I want the programmer to say "initialise E and F after G, H and I". The kernel build system works out the directed graph of initialisation order then controls the execution of startup code to satisfy this graph.

Quoted 8 lines

I don't doubt you will come up with a workable solution at build time. However, working out a valid graph at execution time is trivial and efficient, given a list of precedence relations of the kind you're suggesting. In fact you don't even have to work out the graph before starting the initialization, it's also trivial to keep a count of unsatisfied initialization conditions at the beginning of each initialization sequence and block until the count goes to zero. (In essence, evaluate a priority sort on the fly.)

It is safer to evaluate the graph at link time in case somebody mistakenly codes a dependency loop, that is an abort case. Finding that you have a loop at load time and aborting the kernel is a little too drastic for my tastes.

Quoted 4 lines

In any case it is academic. Linus insists on link order being explicitly and completely specified by the programmer and he likes the link order being implied by Makefile order. So there is no point in working on a better system.

I'm not so sure about that. I think it _should_ be possible to do both, and get better documentation at the same time.

How about this:

* Invent some method for modules to declare these dependencies. Maybe even in /** */ type comments, so it goes right into the documentation.

* Write a program to collect all dependencies, do a tsort on them (alerting the developer if a loop is found), determining a reasonable initialization order, and spitting out the relevant Makefiles or Makefile fragments to *create* that initialization order the Linus way.

Or in other words, don't do it at runtime, don't do it at compile time, do it at develop time. (Or patch time, perhaps.)

MfG Kai
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/

#18 lore raw
In reply to Keith Owens
Quoted 4 lines · [email protected] said:

So you want two services, one static for code that does not do any initialisation and one dynamic for code that does do initialisation. Can you imagine the fun when somebody adds startup code to a routine that was using static registration?

Oh come on. If you change a module from being 'self-contained' and registered at compile time to requiring initialisation it's hardly unreasonable to expect you switch the registration too.

Besides, I'm not going to allow any link order dependencies into code I maintain without them being impossible to avoid - and if anyone's thought about the problem hard enough to convince me to accept such a change, they'll have noticed the need to change the registration.

Quoted 3 lines

Oh dear, I added init code so I have to remember to change from static to dynamic registration, and that affects the link order so now I have to tweak the Makefile.

cf. "Oh dear, I added init code but put it _after_ the registration instead of before, so stuff blows up."

Neither of these two programmers will get their code into anything I maintain.

cf. "Oh dear, I need registration, but I have to remember that inter_module_xxx can't do static registration so now I have to tweak the Makefile."

Quoted 1 line · [email protected] said:

Stick to one method that works for all routines, dynamic registration.

It doesn't work for all routines. It introduces unnecessary brokenness - link order dependencies - where previously there were none.

Quoted 4 lines

If that imposes the occasional need for a couple of extra calls in some routines and for people to think about initialisation order right from the start then so be it, it is a small price to pay for long term stability and ease of maintenance.

I'm thinking about link order. If I _wasn't_ thinking about link order, then I'd just put the lines in the 'right' order in the Makefile and put up with it. But I'm thinking about it, and I object to it. It is absolutely unnecessary in this case.

As far as I'm concerned, fixing the registration problems introduced by the dynamic inter_module_register is a small price to pay for long term stability and ease of maintenance :)

--
dwmw2

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/