Are builtin driver always prioritized over loadable modules? - linux-kernel

According to this note:
When multiple built-in modules (especially drivers) provide the same
capability, they're prioritized by link order specified by the order
listed in Makefile.
Furthermore:
However, the order in this file is
indeterministic (depends on filesystem listing order of installed
modules). This causes confusion.
The solution is two-parted. This patch updates kbuild such that it
generates and installs modules.order which contains the name of
modules ordered according to Makefile.
What happens if a system has multiple drivers providing the same capabilities from which some are built-ins and others are loadable modules?
Which one is prioritized in this case? Is it always the built-in? And how can I change the priority (if this is possible)?
I thought about reordering them in modules.alias or modules.order but this wouldn't work I guess since built-ins are not listed there - right?

I found the answer in the meanwhile and I documented it here:
http://0x0001.de/linux-driver-loading-registration-and-binding
To make a long story short:
Yes, builtin drivers are in general prioritized over loadable drivers.
Just because they are registered first and "first comes first serves" principle while binding.

I don't think there is priority. If you have same drivers instances (one is from builtin and the other from kernel module), eventually you will be ended up with compilation error or module loading error since duplicate definition or something.
If you have "DIFFERENT" drivers on the same hardware, not sure why you are doing that??
Also, if somebody already probed and created devices, the later one cannot do the same thing since there will be conflict.
If you are simply asking "precedence" between builtin module and LKM, definitely, builtin module will be first. Kernel module are sitting on different memory location than kernel. So, LKM is loaded later than kernel.
So, if you are loading the same driver with two different ways at the same time, LKM will have problem because of conflict.

Related

How to specify the physical CoreIDs used for "CLOSE" when specifying OMP_PROC_BIND?

We are trying to optimize HPC applications using OpenMP on a new hardware platform. These applications need precise placement/pinning of their cores or performance falls in half. Currently, we provide the user a custom GOMP_CPU_AFFINITY map for each platform, but this is cumbersome, because it's different on each hardware version, and even platforms with different firmware versions sometimes change their CoreID physical mappings - all things impossible for the user to detect on the fly.
It would be a great help if HPC applications could simply set GOMP_PROC_BIND to "close" and OpenMP would do the right thing for the given platform - but to make this possible, the hardware vendor would need to define what "close" means for each machine. We'd like to do this, but we can't tell how/where OpenMP gets CoreID lists to use for things like close, spread, etc. (For various external requirements, the CoreID spatial pattern on this machine would appear utterly random to a software writer.)
Any advice as to where/how OpenMP defines the CoreID lists for OMP_PROC_BIND so we could configure them? We are comfortable with the idea that we might need a custom version of OpenMP (with altered source code) for this platform if needed.
Thanks, everyone. :)
Jeff
Expanding on what #VictorEijkhout said...
You seem have invented an envirable that I can't find anywhere with Google (GOMP_PROC_BIND), with the OpenMP standard envirable (OMP_PROC_BIND). If GOMP_PROC_BIND exists the name suggests that it is a GNU feature. Note too that one of the two Google hits for GOMP_PROC_BIND says "Code that reads the setting is buggy. Setting is invalid and ignored at runtime." So, if you are setting that it is unsurprising that it has no effect!
I will therefore answer for the more general case of OMP_PROC_BIND.
The binding of OpenMP threads to logicalCPUs clearly has to be done at runtime, since, beyond its ISA, the compiler has no knowledge of the hardware on which the compiled code will run. Therefore you need to be looking at the runtime library code.
I have not looked at GNU's libgomp, but, where it can, LLVM's libomp uses the hwloc library to explore the machine hardware. Since hwloc also includes other useful tools for machine exploration (such as lstopo) it is likely that your effort is best invested in ensuring good hwloc support on your machine, at which point there will be no need to delve inside the OpenMP runtime.

Can Windows device drivers have dependencies?

I wrote a kernel-mode driver using C. When I examined it using dependency walker I saw that it depends on some NT*.dll and HAL.dll.
I have several questions:
When does the OS load these DLLs? I thought kernel is responsible for loading DLLs in that case how can driver load a DLL if it is already in kernel-mode
Why don't the standard C dependencies show up like ucrtbase, concrt, vcruntime, msvcp etc? Would it be possible for a driver to have these dependencies and still function?
(A continuation of the last question). If Windows will still load DLLs even in kernel mode, I don't see why drivers cannot be written in (MS) C++
Thanks,
Most of the API in the driver is exported from ntoskrnl.exe.
Your driver is actually a "kernel module", which is part of a process, just like the modules in Ring3.
The driver's "process" is "System", with a Pid of 4, which you can see in the task manager.
ntoskrnl.exe and HAL.dll are modules in the "System", they will Loaded at system startup, while other modules are loaded at time of use (such as your drivers).
You can write and load "driver DLLs", but I haven't done so yet, so I can't answer that.
Ring3 modules are not loaded into the kernel, so you can't call many common Ring3 APIs, but Microsoft has mostly provided alternative APIs for them.
You can't load the Ring3 module directly into the kernel and call its export function. There may be some very complicated methods or tricks to do this, but it's really not necessary.
You can write drivers in C++, but this is not officially recommended by Microsoft at this time as it will encounter many problems, such as:
Constructors and destructors of global variables cannot be called automatically.
You can't use C++ standard libraries directly.
You can't use new and delete directly, they need to be overridden.
C++ exceptions cannot be used directly, and will consume a lot of stack space if you support them manually. Ring0 driver stack space is usually much smaller than Ring3 application stack space, indicating that BSOD may be caused.
Fortunately:
Some great people have solved most of the problems, such as the automatic calling of constructors and destructors and the use of standard libraries.
GitHub Project Link (But I still don't recommend using standard libraries in the kernel unless it's necessary, because they are too complex and large and can lead to some unanticipated issues)
My friend told me that Microsoft seems to have a small team currently trying to make drivers support C++. But I don't have time to confirm the veracity of this claim.

How compilation and linking at runtime is happening?

In a tutorial I've encountered a new concept (for me), that I never thought is possible. Actually, I thought that compilation is an entirely pre-run-time process. This is the phrase from tutorial: "Compile time occurs before link time (when the output of one or more compiled files are joined together) and runtime (when a program is executed). In some programming languages it may be necessary for some compilation and linking to occur at runtime".
My questions are:
Is pre-run-time compilation and linking processes absolutely different from run-time compilation and linking? If yes, please explain the main differences.
How are code sections that need to be compiled(linked) during run-time marked and where is that information kept? (This may be different from language to language, if possible, please give a specific example).
Thank you very much for your time!
Runtime compilation
The best (most well known) example I'm personally aware of is the just in time compilation used by Java. As you might know Java code is being compiled into bytecode which can be interpreted by the Java Virtual Machine. It's therefore different from let's say C++ which is first fully (preprocessed) compiled (and linked) into an executable which can be ran directly by the OS without any virtual machine.
The Java bytecode is instead interpreted by the VM, which maps them to processor specific instructions. That being said the JVM does JIT, which takes that bytecode and compiles it (during runtime) into machine code. Here we arrive at your second question. Even in Java it can depend on which JVM you are using but basically there are pieces of code called hotspots, the pieces of code that are run frequently and which might be compiled so the application's performance improves. This is done during runtime because the normal compiler does not have (or well might not have) all the necessary data to make a proper judgement which pieces of code are in fact ran frequently. Therefore JIT requires some kind of runtime statistics gathering, which is done parallel to the program execution and is done by the JVM. What kind of statistics are gathered, what can be optimised (compiled in runtime) etc. depends on the implementation (you obviously cannot do everything a normal compiler would do due to memory and time constraints - guess this partly answers the first question? you don't compile everything and usually only a limited set of optimisations are supported in runtime compilation). You can try looking for such info but from my experience usually it's very badly documented and hard to find (at least when it comes to official sources, not presentations/blogs etc.)
Runtime linking
Linker is a different pair of shoes. We cannot use the Java example anymore since it doesn't really have a linker like C or C++ (instead it has a classloader which takes care of loading files and putting it all together).
Usually linking is performed by a linker after the compilation step (static linking), this has pros (no dependencies) and cons (higher memory imprint as we cannot use a shared library, when the library number changes you need to recompile your sources).
Runtime linking (dynamic/late linking) is actually performed by the OS and it's the OS linker's job to first load shared libraries and then attach them to a running process. Furthermore there are also different types of dynamic linking: explicit and implicit. This has the benefit of not having to recompile the source when the version number changes since it's dynamic and library sharing but also drawbacks, what if you have different programs that use the same library but require different versions (look for DLL hell). So yes those two concepts are also quite different.
Again how it's all done, how it's decided what and how should be linked, is OS specific, for instance Microsoft has the dynamic-link library concept.

Is it possible to write a libPOSIX for Windows (Win32) without requiring a background service or DLL that's always loaded?

I know about Cygwin, and I know of its shortcomings. I also know about the slowness of fork, but not why on Earth it's not possible to work around that. I also know Cygwin requires a DLL. I also understand POSIX defines a whole environment (shell, etc...), that's not really what I care about here.
My question is asking if there is another way to tackle the problem. I see more and more of POSIX functionality being implemented by the MinGW projects, but there's no complete solution providing a full-blown (comparable to Linux/Mac/BSD implementation status) POSIX functionality.
The question really boils down to:
Can the Win32 API (as of MSVC20??) be efficiently used to provide a complete POSIX layer over the Windows API?
Perhaps this will turn out to be a full libc that only taps into the OS library for low-level things like filesystem access, threads, and process control. But I don't know exactly what else POSIX consists of. I doubt a library can turn Win32 into a POSIX compliant entiity.
POSIX <> Win32.
If you're trying to write apps that target POSIX, why are you not using some variant of *N*X? If you prefer to run Windows, you can run Linux/BSD/whatever inside Hyper-V/VMWare/Parallels/VirtualBox on your PC/laptop/etc.
Windows used to have a POSIX compliant environment that ran alongside the Win32 subsystem, but was discontinued after NT4 due to lack of demand. Microsoft bought Interix and released Services For Unix (SFU). While it's still available for download, SFU 3.5 is now deprecated and no longer developed or supported.
As to why fork is so slow, you need to understand that fork isn't just "Create a new process", it's "create a new process (itself an expensive operation) which is a duplicate of the calling process along with all memory".
In *N*X, the forked process is mapped to the same memory pages as the parent (i.e. is pretty quick) and is only given new pages as and when the forked process tried to modify any shared pages. This is known as copy on write. This is largely achievable because in UNIX, there is no hard barrier between the parent and forked processes.
In NT, on the other hand, all processes are separated by a barrier enforced by CPU hardware. In NT, the easiest way to spawn a parallel activity which has access to your process' memory and resources, is to create a thread. Threads run within the memory space of the creating process and have access to all of the process' memory and resources.
You can also share data between processes via various forms of IPC, RPC, Named Pipes, mailslots, memory-mapped files but each technique has its own complexities, performance characteristics, etc. Read this for more details.
Because it tries to mimic UNIX, CygWin's 'fork' operation creates a new child process (in its own isolated memory space) and has to duplicate every page of memory in the parent process within the newly forked child. This can be a very costly operation.
Again, if you want to write POSIX code, do so in *N*X, not NT.
How about this
Most of the Unix API is implemented by the POSIX.DLL dynamically loaded (shared) library. Programs linked with POSIX.DLL run under the Win32 subsystem instead of the POSIX subsystem, so programs can freely intermix Unix and Win32 library calls.
From http://en.wikipedia.org/wiki/UWIN
The UWIN environment may be what you're looking for, but note that it is hosted at research.att.com, while UWIN is distributed under a liberal license it is not the GNU license. Also, as it is research for att, and only 2ndarily something that they are distributing for use, there are a lot of issues with documentation.
See more info see my write-up as the last answer for Regarding 'for' loop in KornShell
Hmm main UWIN link is bad link in that post, try
http://www2.research.att.com/sw/download/
Also, You can look at
https://mailman.research.att.com/pipermail/uwin-users/
OR
https://mailman.research.att.com/pipermail/uwin-developers/
To get a sense of the features vs issues.
I hope this helps.
The question really boils down to: Can the Win32 API (as of MSVC20??)
be efficiently used to provide a complete POSIX layer over the Windows
API?
Short answer: No.
"Complete POSIX" means fork(), mmap(), signal() and such, and these are [almost] impossible to implement on NT.
To drive the point home: GNU Hurd has problems with fork() as well, because Hurd kernel is not POSIX.
NT is not POSIX too.
Another difference is persisence:
In POSIX-compliant systems it is possible to create system objects and leave them there. Examples of such objects are named pipes and shared memory objects (shms). You can create a named pipe or a shm, and leave it in the filesystem (or in a special filesystem-like place) where other processes will be able to access it. The downside is that a process might die and fail to clean up after itself, leaving unused objects behind (you know about zombie processes? same thing).
In NT every object is reference-counted, and is destroyed as soon as its last handle is closed. Files are among the few objects that persist.
Symlinks are a filesystem feature, and don't exactly depend on NT kernel, but current implementation (in Vista and later) is incapable of creating object-type-agnostic symlinks. That is, a symlink is either a file or a directory, and must link to either a file or a directory. If the target has wrong type, the symlink won't work. You can give it the right type if the target exists when you create the symlink, but POSIX requires that symlinks may be created without their target existing. I can't imagine a use-case for a symlink that points first to a file, then to a directory, but POSIX says that this should work, and if it doesn't, you're not completely POSIX-compliant. Or if your symlinking API/utility can be given an option that specifies the right type, when target doesn't exist, that also breaks POSIX compatibility.
It is possible to replicate some POSIX features to some degree (such as "integer descriptors from in a single namespace, referencing any I/O object, and being select()able" without sacrificing [much] performance, but that is still a major undertaking, and POSIX interface is really restrictive (that is, if you could just add one more argument to that function, it would have been possible to Do The Right Thing...but you couldn't, unless you want to throw POSIX compliance away).
Your best bet is to not to rely on POSIX features that are difficult to port to non-POSIX systems, or abstract in such a way that lower levels may have separate implementations for different OSes, and upper levels do not care about the details.

load dynamic lib several times into multiple independent scopes

I want to dynamically load a library multiple times into independent scopes, so that each instance has its own memory. Is that possible?
I guess not in a portable way. Is it possible with dlopen and friends on POSIX/Unix/Linux? Or at least I care about MacOSX for my specific case right now (whereby I might need it later on other systems, too).
Background: The lib I want to use was not designed to be multithreading safe. However, it should work fine if each thread just uses an independent instance of the lib.
More background: It is the readline lib. Adding multithreading support there basically would mean to rewrite the whole thing.
so that each instance has its own memory.
Depends on what you mean by "its own memory". Obviously, with POSIX threads, all memory is shared, so an instance of the library can not have "its own memory".
What you probably meant though is "so that each instance has its own copy of global variables", to which the answer is yes: see dlmopen(3) docs. You'll want to pass LM_ID_NEWLM to it.
Beware: this is Linux and Solaris only, and GDB doesn't know anything about libraries loaded into non-default linker space, so debugging problems is currently very hard.

Resources