Microkernel hatred is a peculiar phenomenon. Sheltered users who have never had any background in much beyond Windows and some flavor of free monolithic Unix, will, despite a general apathy or ignorance in the relevant subjects, have strong opinions on the allegedly dreadful performance and impracticality of “icrokernels”, however they define the term (and we shall see that a lot of people have some baffling impressions of what a microkernel is supposed to be). Quite often, these negative views will be a result of various remarks made by Linus Torvalds and a general hero worship of his character, a misrepresentation of an old Usenet flame war between AST and Torvalds that was somehow “won” and which supposedly proved that microkernels are nothing but a toy of ivory tower academics, or a rehash of quarter century-old benchmarks on CMU’s Mach that were unfavorable. The presence of Linus’ character in many of this is no coincidence. It strikes me that anti-microkernel sentiment most vocally originates as a sort of tribal affiliation mechanism by Linux users to ward off insecurity.
In any event, this article will be a concise tour of microkernel myths and misconceptions throughout the ages.
I wouldn’t exactly call this article “concise”, but it’s definitely filled with valuable technical information.
Recently, research projects such as Microsoft’s Singularity O/S have demonstrated that it is possible to bypass hardware memory protection in preference for running only verifiable code that simply demonstrably (provably) cannot access anything outside the set of resources made available to it.
This made their system to avoiding context switches, adopt a Microkernel architecture without accepting one legitimate concern – that context switches really do incur a cost in performance, and these architectures mandate more switches.
Its fascinating stuff, and one of the best bits of real blue-sky thinking (although, as with all good ideas, firmly standing on the shoulders of giants) in O/S design.
Here’s a link (https://en.wikipedia.org/wiki/Singularity_(operating_system) to the Wikipedia article, which is a good overview and gives further links to the project itself.
Are context switches really that big of an issue though?
Edited 2016-01-04 00:58 UTC
Were you just comparing uKernels to monolithic kernels I would say no. Modern ones tend to try and avoid them unless absolutely necessary, and while the results vary tremendously L4, for example, seems to do a very good job of it. In other words they avoid context switching to a large enough degree that its impact is mostly noise relative to comparably monolithic kernels.
But Singularity is a bit different. It doesn’t avoid context switches when going from user mode to kernel mode, it avoids them entirely. It has a single address space, so there never any context switches.
Papers I have seen put the cost of a full context switch at around 30us (average) on modern, high end x86 processors. A really busy machine running lots of busy processes can easily end up doing over 7.5k per second. In other words it is spending ~20% of the time in context switches.
Something that avoids them entirely and can run many, many processes performing some kind of collective work through IPC would benefit from it quite a bit. And the more processes running, the bigger the benefit.
Edited 2016-01-04 08:58 UTC
Singularity avoid switching the MMU. But of course there are context switches. Only that the context is much smaller.
If two or more tasks/processes/threads/execution entities run in parallel on the same core, the OS/scheduler must save and restore information (mostly in CPU registers) about the tasks.
yeah, I was wondering the cost of context switches in the context (pun intended) of micro vs macro kernels. Most of the academic literature I’ve read tended to point towards context switch overhead induced by microkernels being a non issue in the overall scheme of things.
Yes.
Not because microkernels is a bad idea, it is a perfectly good design goal, but it is never implemented as cleanly as it is described, and these days even Linux is not cleanly macrokernel either (loadable modules, user-land services, etc), and original microkernels like modern Windows is more macro.
So use it where it makes sense, especially when writing a new OS, but how often do you do that?
Edited 2016-01-03 00:51 UTC
Well, QNX is a successful microkernel, OSX is pretty much microkernel and the biggest GNU/Hurd problem is the lack of people working on it.
I really don’t buy that “microkernels are too difficult” mantra. Rocket science is difficult too and rockets are launched everyday ha!
IMHO the real “problem” is that macrokernels like Linux/Windows are _GOOD ENOUGH_ for 99.9% of the tasks… so there’s no real incentive to go microkernel. MP3 vs CDs thing.
I think the market (and people in general) always prefers something practical/good to something great. Microkernels are technically super great, every comp-sci student in the world know that and We love them… but Betamax was great too (and the Amiga, and the SACD, and electric cars… and you name it). That “better is enemy of the good” thing rules the fscking world. xD
Not really. It’s structured much like a microkernel, with the various parts of the kernel passing messages in the same way a microkernel might, but the whole thing runs in kernel mode, essentially negating all the advantages a microkernel brings to the table.
It is described as a hybrid kernel, but many think that “hybrid” is just a marketing term, and anything that runs wholly in kernel mode is a monolithic kernel.
Additionally, while IOKit allows drivers to be built to run in usermode, the majority of drivers that ship with OSX run in kernel mode, too.
https://www.google.fr/search?q=design+vs+user+experience&tbm=isch
Emulation fits so well in the microkernel world. Other than the virtual 8086 mode modifications in the kernel, it would be just another branch in the tree.
I’ve always wanted to read more about IBM’s Workplace OS (microkernel + OS personalities).
Just when I thought the new year was going to start off right.
😉
1) Microkernels suck. How badly? VERY badly when compared to monolithic ones in terms of efficiency and performance.
Not just a little, I mean a lot. No kidding. Do you think it is a giant conspiracy by OS engineers to some how not use Micro Kernels? No, it isn’t. Its a fact. The idea simply sucks to modularize at that level on Von Neumann machines. If someone tells you the past 80 years in digital computing somehow every one is stupid and nobody knows any better they are lying to you.
Lets move on shall we?
2) Now that I explained why Microkernels suck. Lets explore why they suck JUST SOOOOOOOOO badly.
First of all, to make a modular kernel/system call level to actually work as efficient as a monolithic OS, large amounts of hardware and complexity would have to be added to todays PC architecture.
That is a problem, but one that can be overcome.
The kicker is, nobody in the academic world can agree as to exactly what a micro kernel is, where it begins and ends in the syscall level and exactly what sorts of security constraints it should have or how it should be organized.
Nope. Nobody agrees. If nobody agrees, and nobody has after 50 plus yeas of looking at this academic NONSENSE, which is what I call it, a micro kernel org standard would emerge.
Just like it did for Monolithic kernels and as a result, we have dedicated hardware to accelerate the standard tasks a Monolithic kernel needs to perform in hardware.
Cept, it never happened for Micro kernels. Why is that do you suppose?
Without everyone agreeing on what a Micro Kernel is, you can’t create a set of hardware designs that will enable a Micro kernel to work.
Anyone here know how expensive it is to lithograph and create chipsets? Let me clue you in: VERY expensive.
Which is really key here. No standard? No processor/chipset support to make the idea of modularizing the address and communication spaces, the whole key parts to making a Microkernel work fast and efficiently.
Intel MANY TIMES, has investigated designing a chipset/processor architecture for Microkernels using a Von Neumann setup. They all failed, or were labeled too costly because the academic idiots don’t even know what they want in a Microkernel.
Hence no standard hardware can be sold to accommodate the proponents of Microkernels.
3) Since almost CERTAINLY a Microkernel hardware platform/processor/chipset combo would be more expensive than a Monolithic kernel (which requires far simpler hardware for some basic address translation features), it would then be a issue of OK, who would buy it?
Especially since using a Monolithic machine is just as secure, fast and efficient?
So let me close with an illustration of how a Microkenel syscall works:
https://www.youtube.com/watch?v=Y8cuuP4Jmio
Well… go tell CISCO who bought a microkernel os (qnx) in order to build their internet backbone systems on it. What would they know?
Please don’t confuse control plane for forwarding. The actual routing engine on most large scale internet routers is no more powerful than a 5 year old laptop computer because all the heavy lifting is being done on ASICs.
IOS XR is built on QNX because of fault tolerance, NOT because of performance. As control plane its job isn’t to be fast, it’s to be reliable. It also needs to distribute various process and data to other routing engines running either on other chassis or as a standby so the microkernel way of message passing is seen as less of a hindrance for the architecture.
The crown jewel of the design was supposed to be in service software upgrades where portions of the OS could be upgraded without need to reboot a control system of an Internet core router each time someone rolls out a bug fix but they have not really been able to capitalize on this because updates typically contain numerous changes which tend to warrant a reload of the whole thing anyway so it doesn’t really do (in practice) the main thing it is supposed to do.
Even with IOS XR they use a hybrid design between QNX And Linux so it isn’t purely just QNX.
Either way the job of the OS in this context is to program hardware and sit back meaning using it as an example of a high performance microkernel is largely bogus. My PC is significantly faster than the routing engines that run on core routers because they only have to reliably process updates to network topology, not packets.
Definitely.
I worked on that.
I often find this the biggest issue. When it comes to net benefits, rarely does it pan out or turn out to be all that useful.
For example, modular upgrades. It never quite worked perfectly, but here’s the kicker. Even if it could be done, the actual people using the router wouldn’t be casually upgrading modules. They have their own test cycles and typically have fail over to take over, while upgrades are done. Again, this is key. Any router used in a major system is going to have HA anyways which theoretically can handle the load. So they’re going to use it anyways.
So the use-case sounds amazing in theory. But in real life, there really wasn’t any.
This can change of course if you can deliver quality over years and people learn to trust things.
In the end, you’re basically better off focusing on quick reboot times than modular loading in these kinds of routers.
I’d love to tell Cisco a lot of things, believe me I would. Do you have a direct number to someone who cares over there?
Hi,
A system call is exactly the same for both micro-kernel and monolithic kernel.
Note that I didn’t watch the video – it’s blocked (in my country at least) due to copyright infringement.
– Brendan
Are you deliberately being this idiotic? How many system calls are there in a microkernel and how much context switching goes on? Hint: It’s a lot more than a monolithic kernel……which is why monolithic kernels have been ubiquitous and why minimising system calls, context switching and IPC is always important. Microkernel idiots have been parroting for years that faster hardware would make these concerns go away. Obviously not so.
To make a microkernel perform acceptably you’d have to implement large parts of it in hardware and so have to make assumptions about architecture.
Every man and his f–king dog pops their head up every few years and tells us how microkernels are misunderstood, attempts to debunk some ‘myths’ and how it’s the future everywhere. Incredible stupidity is attempting the same thing over and over for decades on end and expecting a different result. Microkernels exist for reasons that exist only in the minds of certain people, such as driver instability. This really only works in specific cases and is a huge price to pay in overall performance.
Edited 2016-01-04 12:30 UTC
Hi,
Actually; it’s a smaller price than running multiple instances of the OS inside separate virtual machines, which is something that’s become common (for servers) simply because things like “chroot jails” only solve part of the problem.
Incredible stupidity is attempting the same thing over and over for decades on end and expecting a different result; like trying to build a secure monolithic kernel. Why do you think Microsoft has mandatory device driver signing and a full certification process; and Linux developers get all whiny and scared when they see a binary blob; and both of these have > 100 critical vulnerabilities per year anyway?
– Brendan
Alas, those ‘security problems’ are very much hypothetical and not worth the effort effectively destroying acceptable performance and making a kernel unusable. Once you get down to a kernel level you have privileged code and there is simply no getting around that. When you begin ‘untrusting’ all kernel code you end up performing a great deal of extremely sad academic mental gymnastics that microkernel people get themselves into.
I’ve had conversations with hypervisor people who are overflowing with hypothetical security problems whilst greatly increasing the complexity of their systems to support separation and also leaving them unable to reuse tried and tested code.
Hi,
Yes. That’s because most hyper-visors have a massive amount of code running at the highest privilege level (on the host), just like a monolithic kernel.
– Brendan
Agreed on all points, but performance concerns. There is a reason why all of the examples of “good” micro kernels are all embedded RTOS style OSes. The lack of performance on the specific hardware, only has a small cost associated with it. For those specific use cases, the reliability matters more than the extra pennies per unit.
> Which is really key here. No standard? No processor/chipset support to make the idea of modularizing the address and communication spaces, the whole key parts to making a Microkernel work fast and efficiently.
Wrong. That’s exactly what IOMMU hardware does on recent x86_64. You might know it as VT-d or “that stuff I need to get GPU passthrough working right in KVM.” And hey, what do you know, giving a VM direct access to physical hardware looks a LOT like a microkernel with protected address spaces and user-mode drivers. Recent x86_64 microkernel research is leaning on the IOMMU hardware for enforcement just like VM hypervisors.
Yes, having to be implemented in hardware for performance reasons and in a specific scenario where it actually makes sense to do so.
Alas, you’d have to implement a lot more in hardware to make a microkernel realistic in terms of performance.
Sums it up quite nicely.
couldn’t (when looking at it from some POV’s) a Hypervisor be considered a Microkernel?
It’s more of an exokernel.
In practice, hypervisors, like Xen or ESXi, are our ghetto microkernels!!! For sure!! haha
But Xen and VMware still run using monolithic kernels based on Linux and they have exactly the same problems as Linux/Windows/Solaris.
For example: if you have to update a module/driver on an ESXi/Xen host, yeap, in most cases you have to reboot it!!! If you have a stalled LUN or stuck multipath stack or something related to “un-interruptable” scsi commands issue… yes, you have to reboot!!! (usually a hard reboot). So… problems are the same.
As I said, with hypervisors We gained a lot of microkernel’s advantages following a different path (just to avoid the fundamental problem)… but the fundamental problem is still there laughing at us: monolithics kernels suck and the OSes that We are used to use suck too because We have exactly the same problems that We had 30 years ago.
But as you know, people like Linus Torvalds have their agendas and they will tell you that Linux is wonderful and monolithic kernels are perfectly fine (even if we try to develop technologies to avoid their problems all the time!! i.e ksplice, i.e hypervisors, ecc). Well, let me tell you: Windows/Linux/Solaris are not fine, in fact, ancient OSes like VMS/OpenVMS were 1000x better than the shit We are used to use today.
But hey, this is the IT world… money and mediocrity rules.
The particular problem of needing to reboot on an upgrade isn’t really that much of a problem, at least compared to the problem of coming up with a new operating system that might (only might) be able to accomplish this. Making an operating system is just the first step, there has to be a platform and community around it.
I mean, yeah, I’d rather have the ability to upgrade a module in flight rather than reboot, but it’s such an easy thing to work around that it doesn’t even register against the noise of other challenges we have in IT.
And are VMS/OpenVMS really better than what we’ve got today? Depends on your measure of better. For me, it’s can I do the things I need to do on modern systems. And the answer for that is obviously no. So no, they’re not better.
So yeah, Windows/Linux/Solaris are fine. None of them are perfect, and there’s constant evolution in them. But they’re a lot better than hypothetical, unproven implementations (and by proof, I mean running real workloads) or ancient operating systems that while useful in their day, aren’t useless anymore. I’m all for better technology and better solutions, but purity for purity sake isn’t a solution.
Valuable information?
Those who can, code. Those who can’t, write about it.
Nothing new here.
Many years ago when there were questions about whether Torvald had copied Minix code into Linux, I pulled up old copies of both and compared the implementation code in each for one particular system call – I think it was the “open” call. The Linux code was straightforward – it consisted of a function with parameters (file name and flags) passed as arguments to the function in standard C fashion. The Minix code was also implemented as a function, but it had no arguments. How did the parameters get in? They came in through global message blocks, but the way in which they worked was a tangle of spaghetti code – opaque #defines, declarations split across multiple files and different subdirectories – yuk! No one in their right mind would attempt to copy such code. Don’t know if that has anything to do with the micro/macro kernel argument.
Hi,
For a micro-kernel, the kernel doesn’t implement “open()” at all. What it does is implement some sort of communication that is used to send something (e.g. an “open file request” message) to another process (e.g. the virtual file system layer).
This communication is used a lot, so it’s designed carefully and implemented to minimise overhead. It tends to play a significant role in scheduling (tasks blocking while waiting for a message and unblocking when they receive), and (for some micro-kernels and not others) may have a built in permission system (who can send what to who).
Mostly, if you were looking for something that resembles Linux’s “open()” you were looking in the wrong place; and shouldn’t be surprised that what you found in Minix doesn’t look anything like what you found in Linux.
Also note that one specific micro-kernel is not all micro-kernels.
It’s entirely possible for someone to dislike Minix’s code but like micro-kernels. I am someone like this (I think synchronous message passing is inferior to asynchronous message passing, especially for modern/multi-CPU systems; I think the kernel’s messaging shouldn’t be bloated up with a permission system and it should be left to the receiver to either accept or reject; etc).
In the same way it’s possible for someone to dislike Linux’s code and still like monolithic kernels. I am someone like this too (Linux was original a beginner/amateur’s project and has fundamental design flaws in key areas, like memory management and scheduling, that became unfixable because too much code depends on these early design flaws; and kernels like FreeBSD and Solaris are technically superior).
– Brendan
I’ll take your word for it, but here’s a few lines of Minix file “open.c”:
————
/* This file contains the procedures for creating, opening, closing, and
* seeking on files.
*/
————
PUBLIC int do_open()
{
/* Perform the open(name, mode) system call. */
————
Maybe Minix wasn’t such a “microkernel” after all.
Hi,
As far as I can tell, that’s this file: http://www.cise.ufl.edu/~cop4600/cgi-bin/lxr/http/source.cgi/fs/ope…
Note that this is from the “minix/fs” directory and not from “minix/kernel” directory. This is because you’re not even looking at the kernel’s source code to begin with. You’re looking at the “fs” service (that runs as a process in user-space).
– Brendan
Did you actually type that with a straight face?
Can you sort of understand why that would be a huge problem when people start thinking about the thorny issue of performance?
Basing your interactions on message passing means you can do cool shit along the lines of Plan 9. Even if there *is* a local performance penalty, the advantage of accessing local and remote resources using the same protocol far outweighs the cost.
Does it? People have been getting along fine without it.
Once you get into IPC mechanisms within a kernel you are sunk.
Trust me, there is a performance penalty and a big one. I’m afraid given how prevalent microkernels are, which is not very, that is simply not borne out by facts.
Hi,
I understand that it can be a minor performance sacrifice (in exchange for more important advantages).
– Brendan
Excuse me, my sides have split. That performance sacrifice where any IPC (and with memory copying and copying of any data structures) is concerned is absolutely enormous and it is prohibitive enough that there are very few microkernel based operating systems around – and they will dwindle further. That debunks everything here and cuts to the heart of the matter. Microkernels live in a bubble in academia where there are no performance penalties for any of this or where they can be waved away nebulously as acceptable, and sadly people still live in a strange world where that is the case.
Edited 2016-01-04 23:39 UTC
Hi,
Do you have any actual facts to back up your ignorant drivel?
Macro-benchmarks (not biased/worthless micro-benchmarks) have shown L4Linux running normal processes (e.g. compiling something large) to be between 5% and 10% slower than doing exactly the same under Linux.
Sure, 5% to 10% isn’t great, but that’s acceptable for a lot of use cases (e.g. plenty of programmers using managed languages take a 5% to 10% performance loss for the sake of safety and nobody seems to care). However; let’s put this into its proper perspective.
It’s literally a micro-kernel written on a budget by a university (and not something companies have invested billions of $$ in like Linux), running a massive pile of bloat (the full Linux kernel) in user space, and then running processes that were designed for Linux underneath that; and it’s only 5% to 10% slower.
Let’s put this another way. If you ran a copy of the Linux kernel as a process underneath another Linux kernel, how much performance would you expect to lose? Would you be surprised to learn that “Linux under Linux” (User Mode Linux) has been benchmarked and is slower than “Linux under L4” (L4Linux)? That is a fair comparison.
Now imagine what would happen to that 5% to 10% if the processes were actually designed for the micro-kernel (e.g. and were using raw message passing, and not “less well suited” APIs like POSIX that were designed for monolithic OSs), and if you disposed of that massive pile of bloated “Linux kernel middle-ware”. You’d be able to do a fair comparison between “micro-kernel running processes designed for micro-kernel” and “monolithic running processes designed for monolithic”.
Sadly; fair comparisons like this are almost impossible to find. Virtually all of the micro-kernel developers (QNX, L4, Minix, etc) take a completely inappropriate user-space and glue it underneath their kernel. It’s insane. It’d be like designing an entire user-space around message passing, running it under a monolithic OS that was never designed for it (and using something like pipes or sockets to mimic message passing), and then complaining that monolithic OS performance sucks.
– Brendan
In the case of QNX Neutrino they designed the kernel to be a good fit to the Posix standard and the amount of glue is tiny. By using the native IPC channels as the file descriptors read()/write() map directly to the internal interface. Very clean.
Hi,
This is a little complicated…
A lot of the C/POSIX functions (especially for IO) can block. For example, you call “open()” and your thread has to wait for a result. Under a micro-kernel this might mean your thread sends a message to VFS layer and blocks, then a task switch happens, then VFS layer handles the request and sends a reply that unblocks you, then another task switch happens because your thread can run now.
If you want to open 10 files you get 20 task switches; simply because “open()” (and a whole bunch of other functions) will cause the thread to block. That’s why a lot of micro-kernel research/effort has gone into making synchronous IPC and task switches fast.
What if we say “screw POSIX”?
If we want to open 10 files, we can send 10 messages to the VFS layer, then do one task switch, the VFS layer can handle all of them and send 10 replies, and then we can do one task switch back. Alternatively, you could also just send a single message saying “open this list of 10 files”. Instead of 20 tasks switches it drops to 2 task switches.
But.. why stop there? If your thread is running on one CPU and has other work it can do while its waiting (or is just “pre-opening” the files for later); and if the VFS layer is running on a different CPU (and handling requests from other processes); then…
Zero task switches.
Of course that’s best case (e.g. it can’t happen for single-CPU) and you’re not going to be that lucky all the time; and not all of the overhead is from task switches. However, you can significantly reduce the number of task switches and significantly reduce the overhead (especially under load), as long as you’re willing to say “screw POSIX”.
– Brendan
No. Because it isn’t one – as shown by research.
Kind of interested why you think linux memory management or scheduling is baddly done and unfixable. Kernel scheduling is an interest to me. Any further sources I could look at ( aside from pointing me to openIndiana, freebsd, and linux source code)?
Windows NT 3.5.1 was the the best designed Windows kernel ever, IMO.
If MS had stuck with the original design, we would never have had a huge majority of all the security issues we see with Windows over the past 20 years.
The irony is, all the security patches and buffer checks MS has put in their operating systems have taken a huge toll performance wise, and it they would have stuck with the original pure microkernel, we likely would have a faster, more efficient OS today.
For those who don’t know, the original Windows NT 3.5 was a pure microkernel, and then in 4.0, MS switched to a hybrid model, where most of the UI processes got moved to the kernel.
The problem with monolithic kernels is everything is in the same address space, any issue with any kernel driver or component can take down the whole system.
And all of the performance issues with the early pure microkernel OS have been resolved.
A problem Windows 3.5.1 had as well. Sure, GDI was in userspace, but that didn’t do much good when 9 out of 10 times a crash in it was unrecoverable. Yeah! The kernel survived the crash! To bad there is no longer any way to interact with it… And it certainly didn’t help with file systems, or network drivers, or anything else really since as far as those are concerned 3.5.1 was a monolithic kernel.
Yes and no. This argument is actually covered by the article and he points out that a microkernel can apply methods to restart processes that stopped functioning properly.
You already see this principle on modern Windows with (parts of) the graphics driver. I’ve several times managed to crash my Nvidia driver, which in the Windows XP days would have blue screened my computer. Since Vista this just causes a small popup to appear telling me that the graphics usermode driver was restarted.
Of course, for security bugs you’re absolutely right. Except maybe that in kernel space a bug gave you access to *everything*.
Yes. And Windows NT cannot do that with file systems, (which was my specific example). It can do that (as you mention later), to a limited degree, with the user mode portion of the video driver (at least since Vista). However, the ability to do such a thing in a specific subsystem has nothing to do with whether or not the underlying OS is microkernel based…
The kernel mode/user mode split in the WDDM driver model for video drivers is an implementation detail of the driver model, it does not rely on the services of a microkernel to exist. They just moved the parts of the driver that don’t need to be in the kernel into user space. Linux does much the same thing with X, and it certainly isn’t a microkernel.
I have no qualms with microkernels. What I am arguing about is whether or not the kernel in Windows NT was ever a microkernel. It is not, and never was. Simply based on how the kernel implements IPC, it is quite obvious that if an attempt were made to convert it into one utilizing it’s existing design, it simply would not work (not flexible enough and FAR too slow to be usable).
There is a reason it runs almost everything in kernel mode… It is because it was designed to. The notion of it having been a true microkernel at any point in its history is ridiculous.
I never claimed it was. My graphics driver example was just an obvious case of why it makes all the difference whether the bug appeared in userspace or kernelspace.
My original comment was only meant to contradict the belief held by the poster I was responding to that a uKernel somehow magically makes bugs disappear. All I’m saying is uKernels simply move the bug, they don’t fix it.
I concede that there is a world of difference between a bug in user mode and a bug in kernel mode. But depending on the bug, and the subsystem it affects, in a rather large number of cases such distinctions don’t really matter – because either way the result is “it don’t work”.
Being able to restart a process that doesn’t work isn’t all that useful most of the time. It can be, in specific scenarios, but it is just as likely that the result will be it just ends up getting restarted again. and again. and again. If it is a rather exotic bug that only gets hit once in a blue moon it can make a huge difference, but then again if it is say a hardware interaction bug (a much more common case) it won’t matter at all since it is just going to crash again momentarily.
Then you have the nightmare of a problem of dealing with state restoration in such cases (for example, file system resurrection in Minux)… Yes, uKernel designs make this kind of thing more manageable at least, but it isn’t without complexity costs and performance penalties.
My only point is ultimately the bug has to be fixed. It makes no difference whether it is in user space or not, its still a bug. The benefit of the kernel surviving such a bug induced crash may not always be particularly compelling for the user.
There is, in my opinion, a rather compelling argument to be made that the people working on an OS are better serving their users by finding and fixing bugs than by trying to engineer Rube Goldberg like contraptions to make them somehow more tolerable. I don’t think all uKernels suffer from this kind of priority inversion, but Minux sure as hell does.
Sure, you could argue that adding this kind of resilience is harder than fixing the bugs. The only problem with this kind of argument is that the crashing driver has a nasty tendency to be 3rd party (like the nvidia driver). Not so trivial. Why do you think Microsoft moved the majority of the graphics driver to usermode?
dpJudas,
While it doesn’t quite “fit” with the rest of the win32s, MS undoubtedly chose a streaming design for DirectX over a more conventional syscall banging for performance. Streams are perfectly suited for microkernels with no overhead compared to macrokernels.
A side benefit of this design is that it is what makes hardware acceleration efficient. Otherwise using more conventional syscalls to build hardware streams in the kernel using would be slow as heck.
This is true regardless of what API call you’re doing. If you perform a file read syscall for 1 byte at a time the overhead is insane. So you buffer it.
Using command queues like OpenGL/Direct3D does is naturally even more efficient but it isn’t required anymore in a microkernel than a normal one. There is nothing that mandates that a syscall needs to be asynchronous. The microkernel could just as easily switch execution immediately to the receiving process as it can run things in kernel mode.
dpJudas,
Even if new APIs are not mandated, without them the full potential of microkernels won’t be unlocked. People may laugh at what I’m about to say, but mainframe developers had mastered many of these design concepts. It seems much of that has been forgotten.
Edited 2016-01-04 08:51 UTC
It’s not so much forgotten as it is just really cumbersome. To use any of the useful mainframe design, you have to go right down to the assembler and macro libraries. You also have the benefit of dedicated IO processors for hard drives, networking, gpus and cryptography that you can program directly if you needed to.
It also helps that z/Architecture was designed from its early origins to run a hypervisor – namely z/VM, so all the issues of isolation without sacrificing performance are somewhat mitigated (and somewhat easier to implement).
Edited 2016-01-04 10:38 UTC
kwan_e,
Sure, but don’t forget that even hardware accelerators need asynchronous/parallel loads to achieve acceleration. If hardware supports a queue depth of 64, but your load is blocked on one or two sequential operations at a time, it’s fundamentally not going to be able to max out the hardware. It’s good that we’re learning to build multithreaded programs to achieve higher degrees of parallelism, but I still think there would be benefit in relearning some of the tricks of the past.
Edited 2016-01-04 20:44 UTC
I actually agree with you completely. I just have a pet peeve about how terms are thrown about. “Pure microkernel” means a very specific thing in academia, and the NT kernel is (and always was) about as far from one as you can get.
That doesn’t in any way make it “bad”. It just isn’t a microkernel. There is far more similarity between NT and Linux when it comes to kernel design than say NT and L4, or NT and QNX.
At least with something like XNU in OSX, you could make the argument that it started out as a uKernel (Mach), but memory isolation and IPC semantics were selectively broken down and removed from most subsystems for the sake of performance. Mach had so many performance problems though that such capitulation for the sake of performance was basically a prerequisite to it being usable – it never really “worked” as a uKernel.
NT is different. It never had such isolation or internal IPC to begin with, and is fundamentally incapable of it (even slowly). It wasn’t ever designed with that usage model in mind. It was originally intended to (and did to a degree) run “personality” processes to implement foreign OS subsystems (OS/2, posix), but it did this in a very crude and incomplete way. Again, Linux can run L4/Fiasco in userspace too, but that doesn’t make Linux a uKernel OS…
You can always move things out of the kernel selectively and gain some robustness advantages. Linux has FUSE file systems, and there is your example with OpenGL drivers. You could certainly call things like this “inspired” by microkernel designs, but they don’t in and of themselves turn your kernel into one…
I’m just saying it is important to call things what they actually are. Words matter. The Windows NT kernel is no closer to being a uKernel than the Linux kernel is, because both contain significant trade offs in their designs which disqualify them from carrying that label.
Actually the NT kernel does communicate with itself through messages:
http://blogs.msdn.com/b/ntdebugging/archive/2007/07/26/lpc-local-pr…
It uses the LPC/ALPC api, which currently is undocumented, though I’m starting to use it in an app we’re developing here.
The NT LCP (local procedure call) messaging system is very similar to Mach messages which is how the XNU kernel communicates with itself.
The NT implementation is extremely good, based on my initial testing, its faster than Mach messages.
The point here is that the NT kernel communicates with itself though messages, and though much of it may be in the same address space, it logically operates very similarly to microkernels, so it is actually most similar to OS X XNU kernel, where both of them are hybrid kernels.
The Linux kernel is more based on standard function calls, which is one of the reasons why its a classic monolithic kernel.
I really wish MS would document the NT LPC/ALPC messaging system, it is used in a large number of their applications such as Skype, and its a damned good system.
Yes, it has varying forms of IPC. But none of them are performant enough to facilitate the pervasive use of it as you would find in a uKernel.
Im not saying it doesn’t use messaging within the kernel. Im saying it doesn’t have a performant mechanism to do so between kernel mode and user mode. Passing such messages, even using (A)LPC, requires buffer copying, as you said much the same as Mach. That is fundamentally what is wrong with Mach, and why it never worked as a uKernel. Buffering is simply too slow. Modern uKernels such as L4 and QNX go to great lengths, and make some rather fundamental tradeoffs, to avoid buffering in all but the most extraordinary cases (which is why they actually perform well enough to be competitive).
While in-kernel IPC such as NT uses can be made very fast since you can avoid the buffering, you lose the memory space isolation, which imo is the whole point of a microkernel.
I do appreciate the other advantages of such a design (modularity, separation of concerns, avoidance of shared data structures, etc.), it still isn’t a microkernel. It just a better engineered monolithic kernel (or “hybrid” if you prefer that term).
The NT kernel most definitively has many microkernel design aspects to it.
Edited 2016-01-05 19:15 UTC
Hi,
In general; a micro-kernel sacrifices a small amount of performance (due to communication overheads) in exchange for a large amount of isolation (which allows other things, like better security, more fault tolerance, more flexibility, etc).
The first problem with micro-kernels is that it’s easy to benchmark performance (and easy to see the small disadvantage, and even easier to use micro-benchmarks that exacerbate pathological cases to fool suckers), and impossible to benchmark “isolation” (and extremely hard to see the huge advantage in practical comparisons).
The second problem is that, for any OS, the kernel is just a relatively small piece. The majority of the work is in user-space – things like GUIs, web browsers, office applications, database management engines, etc. Because of this, most “OS developers” end up being kernel developers – the entire user-space is too hard/time consuming so they recycle an existing open source user-space. Existing open source user-space is built on top of APIs (C and C++ standard library, POSIX API, etc) that were designed for monolithic kernels that are “less well suited” to micro-kernels. This makes micro-kernels seem worse (in the same way that monolithic kernels would seem worse if the APIs that user-space is built on were designed for message passing).
Finally; (especially for desktop and server) it’s extremely hard to get market share for any new OS, regardless of what it is and regardless of how awesome it is. You can’t attract many users without applications and drivers, and you can’t attract application and device driver developers without users. This means that the OS market tends to be dominated by whoever was there first, not because the older OSs are better (or because they’re monolithic), but because they’re established products.
Basically; the real problems with micro-kernels are not technical problems, they’re marketing problems. This is why micro-kernels have only been successful in areas where marketing has less influence (e.g. embedded systems) and aren’t used for desktop/server.
Ironically; this is insane/backwards. For embedded systems (where the total amount of code is small, you don’t need to care about third-party software, and performance and size matters) monolithic kernels should be superior (but mostly aren’t used); and for desktop/server (where there’s no resource constraints, third-party software is unavoidable, and all the performance is mostly wasted due to Wirth’s law anyway) micro-kernels should be superior (but mostly aren’t used).
– Brendan
yeap, correct again
No actually. ‘Security’ is brought up by microkernel proponents because it is simply all that they have. The security examples cited are always incredibly hypothetical and would basically end up in an unusable kernel.
The differences are real, and there are advantages to both. But the article really jumped on the crazy train when it started hypothesizing about a successful Hurd in the 90’s. Its kind of like saying how great of a Jedi I would be, if this was actually the star wars universe. ( BTW, I’d be one of the worst Jedi masters.)
Hurd was/ is insanely more complex than just a microkernel. Which is why its still not really ready, and basically everyone ditched the theoretical benefits for the practical benefits of the working Linux kernel.
I see a lot of stuff suggesting that Linus got it wrong and Andrew was right all along …. just a continuation of the same discussion from 20 years ago.
It’s interesting, but that’s all.
If and when someone writes a microkernal OS that displaces Linux it’ll be significant. Until then it’s just a difference of opinion.
I’m sticking with safer topics like Politics and Religion.
I’m guessing you’re not buying the article’s premise?
I’d agree, but obviously “slow” is a relative term and the niche’s that microkernels live in is different than macros. Making them difficult to compare. And really, its tough enough to bench mark operating systems designed for the same workloads and sharing substantial parts ( ubuntu vs RHEL for example).
All I want is a 64-bit micro-kernel SASOS with a strong whiff of Amiga (yeah, die-hard Amiga dude) plus a versioning filesystem.
And some processor support for better sharing and protecting memory without flushing caches.
World peace might as well come sooner…
Exactly my dream as well…
Is there an elegant (fast) way to make a SASOS secure?
I think you would need MMU support for multiple IDs at once. As in, a page have one ID and a process would have a number of IDs associated with it that identifies which pages it can access.
A context switch changes the current ID associations and the need to flush the cache goes away.
If you can associate a process with only 1 ID then you are basically doing exactly the same as you do today (except you can stop flushing the cache).
As is obvious, this (as so many other CS topics – “0, 1, or infinite”) isn’t obvious how to handle once you go past 0 or 1 IDs. A fixed number of registers will always be a headache. You end up with something like another cache handler in hw or sw.
Possibly can the protection rings principle be used or maybe range use can offer something.
Anyone know some other approaches to read-sharing/read-write-sharing/handover (for either pages or address ranges, and for frequent and many uses at once preferably)?
Itanium systems are pretty cheap on ebay nowadays =)
http://www.bottomupcs.com/hardware_support_for_virtual_memory.html
https://en.m.wikipedia.org/wiki/Quark_(kernel)
The article is full of strong opinions but also some really interesting facts. It also shows the apodictic statements that not always the best is the most successful and there is no right solution for all the usecases. See x86 – its really far away from beeing the best CPU architecture but managed to gain broad acceptance anyways. Sometimes it also needs some time for the best to get that acceptance. See parallel programming. It needs a certain kind of thinking and i know programmers who still are’nt able to handle concurrency.