The rest of the 6.8 merge window
maybe a bit smaller than usual", but 12,239 non-merge changesets found their way into the mainline, so it's not that small. About 8,000 of those changes were merged since the first-half summary was written; the second half saw a lot of device-driver updates, but there were other interesting changes as well.
Some of the most significant changes pulled in the latter half of the 6.8 merge window are:
Architecture-specific
- The riscv architecture has made more information about supported ISA extensions on the current system available via the riscv_hwprobe() system call. See Documentation/arch/riscv/hwprobe.rst for details on what is available.
- Riscv can also now suspend to RAM if the SUSP SBI extension is present.
- Host-side support for Intel Trust Domain Extensions (TDX) has been merged; this will eventually allow KVM to create TDX-protected guests. This documentation commit has some more information.
- The LoongArch architecture has added support for modules written in Rust. This architecture has also raised the minimum version of Clang that can be used to 18.0.0 — which has not been released yet.
Core kernel
- It is now possible to change the size of tracing sub-buffers used for the reporting of trace events to user space; see this documentation commit for more information.
- One new "feature" — the scheduler performance regression encountered by Torvalds early in the merge window — has been removed with this fix.
Filesystems and block I/O
- The
device-mappermulti-device MD_LINEAR, MD_MULTIPATH, and MD_FAULTY targets have been deprecated since the 5.14 release in 2021; they have now been removed.
Hardware support
- Clock: Qualcomm SC8280XP camera clock controllers, Qualcomm SM8650 global clock controllers, Qualcomm SM8650 TCSR clock controllers, Qualcomm SM8650 display clock controllers, Qualcomm SM8650 GPU clock controllers, Qualcomm QDU1000/QRU1000 ECPRI clock controllers, Qualcomm X1E80100 global clock controllers, MediaTek MT7988 clock controllers, Nuvoton MA35D1 realtime clocks, TI TPS6594 realtime clocks, and Analog Devices MAX31335 automotive realtime clocks.
- GPIO and pin control: Realtek DHC GPIO controllers, Nuvoton BMC NPCM7xx/NPCM8xx SGPIO controllers, Qualcomm SM8550 LPASS LPI pin controllers, Qualcomm SM8650, SM4450 and X1E80100 pin controllers, TI TPS6594 PMIC GPIO controllers, and Intel Meteor Point pin controllers.
- Graphics: Imagination Technologies PowerVR (Series 6 and later) and IMG GPUs, Synaptics R63353-based panels, and Ilitek ILI9805-based panels. Also merged is the Intel "Xe" driver for GPUs starting with the Tiger Lake generation. It is not enabled by default anywhere but that will change in some future kernel development cycle.
- Hardware monitoring: Monolithic Power Systems MP5990 hot-swap controllers, Monolithic Power Systems mp2856/mp2857 modulation controllers, Analog Devices LTC4286 and LTC4287 hot-swap controllers, and Gigabyte Waterforce X240/X280/X360 AIO CPU coolers.
- Industrial I/O: Maxim max34408/max344089 analog-to-digital converters, Bosch BMI323 I2C and SPI controllers, Microchip MCP9600 thermocouple EMF converters, Vishay VEML6075 UVA and UVB light sensors, Intersil ISL76682 light sensors, Melexis MLX90635 contactless infrared sensors, Honeywell HSC/SSC TruStability pressure sensors, Lite-On LTR-390UV-01 ambient light and UV sensors, Aosong AGS02MA TVOC sensors, Microchip MCP4801/02/11/12/21/22 digital-to-analog converters, and Analog Devices AD7091R8 analog-to-digital converters.
- LED: Allwinner A100 RGB LED controllers and Maxim 5970 indication LEDs.
- Media: Starfive camera subsystems, Chips&Media Wave codecs, GalaxyCore GC2145 and GC0308 sensors, THine THP7312 image signal processors, STMicroelectronics STM32 memory interface pixel processors, Techwell TW9900 video decoders, Allied Vision ALVIUM MIPI CSI-2 cameras, and OmniVision OV64A40 sensors.
- Miscellaneous: Apple SoC mailboxes, Qualcomm PMIC PDCharger ULOG providers, Microchip MCP2200 HID USB-to-GPIO bridges, Nintendo NSO controllers, AWS EC2 Nitro security modules, Intel visual sensing controllers, AMD AXI 1-wire bus host interfaces, Qualcomm SM8650, SM6115 and X1E80100 interconnects, MPS MP3309C backlight controllers, Adafruit Mini I2C gamepads, and Loongson LS2X APB DMA controllers.
- Sound: Qualcomm X1E80100 audio subsystems and Qualcomm WCD939x USBSS analog audio switches.
Miscellaneous
- The perf tool has gained support for data-type profiling. Some more details, along with information on a the usual large pile of other perf changes, can be found in this merge message.
Security-related
- See this blog post from Paul Moore covering changes to the kernel's security subsystem in detail.
- The AppArmor security module has switched its policy-hash verification from the SHA-1 hash to SHA-256.
- The task of removing the strlcpy() API from the kernel is now complete.
Virtualization and containers
- The guest-first memory feature for KVM has been merged. Guest-first memory can be allocated for and mapped into KVM guests, but is inaccessible to the host, making it suited to confidential-computing applications. There is also a new ioctl() call where the expected attributes for guest memory (including a lack of mapping in the host) can be specified. This changelog has some more information.
- KVM on arm64 systems has gained support for 52-bit (LPA2) physical addresses.
- KVM on x86 can now be built without Hyper-V emulation support, reducing the size of the resulting kernel.
Internal kernel changes
- The kernel now has a .editorconfig file that will automatically configure editors to the kernel's coding style.
- The new check-uapi.sh script can be used to detect inadvertent changes to the kernel's user-space API. See Documentation/dev-tools/checkuapi.rst for details.
If all goes according to plan (which it pretty much always does), the 6.8
kernel will be released on March 10 or 17. Between now and then,
though, there will certainly be a lot of bugs to find and fix.
Index entries for this article | |
---|---|
Kernel | Releases/6.8 |
Posted Jan 22, 2024 20:19 UTC (Mon)
by ju3Ceemi (subscriber, #102464)
[Link] (1 responses)
Posted Jan 22, 2024 20:50 UTC (Mon)
by corbet (editor, #1)
[Link]
Posted Jan 23, 2024 4:47 UTC (Tue)
by mirabilos (subscriber, #84359)
[Link] (2 responses)
Hah.
Does nobody else see how ridiculous this “Rust” fad is?
Posted Jan 23, 2024 5:30 UTC (Tue)
by pbonzini (subscriber, #60935)
[Link]
A bit of prejudice perhaps?
Posted Jan 23, 2024 14:33 UTC (Tue)
by atnot (subscriber, #124910)
[Link]
> The existing mainline clang development version encounters diffculties
https://lore.kernel.org/loongarch/CAAhV-H7Qu9yj1d+fAcE3vL...
And the previous patch:
> By the way, the clang 17.0.0 still have some issues to build kernel on
https://lore.kernel.org/all/1690871446-23713-1-git-send-e...
So it sounds like the LoongArch support in clang/llvm is just very immature and broken. I'm kind of more surprised that they managed to get tier 2 rustc support in this state at all, they have a pretty low tolerance for build failures. Perhaps the kernel is just hitting some weird edge cases.
Posted Jan 23, 2024 8:39 UTC (Tue)
by Lionel_Debroux (subscriber, #30014)
[Link] (46 responses)
Posted Jan 23, 2024 12:01 UTC (Tue)
by make (subscriber, #62794)
[Link] (26 responses)
Posted Jan 23, 2024 14:30 UTC (Tue)
by khim (subscriber, #9252)
[Link] (25 responses)
C++ offers very impressive collection of footguns of various sizes and colors. With people who complain about “arbitrary statement reordering” you can 100% sure all these footguns would be discovered and [ab]used. And if the end result is even more fragile and unstable code then what's the point?
Posted Jan 23, 2024 16:12 UTC (Tue)
by adobriyan (subscriber, #30858)
[Link] (12 responses)
Nominally evaluation order became stricter not looser as standard version increases.
std::initializer_list<> guarantees left-to-right evaluation order as does operator<<.
operator<< looks irrelevant for kernel and std::initializer_list<> being array of references is quite a footgun by itself, but not in the evaluation order department.
Posted Jan 23, 2024 16:39 UTC (Tue)
by timon (guest, #152974)
[Link] (6 responses)
I think this is about the mismatch between kernel developers and compiler developers, namely that kernel developers want the compiler to emit common-sensical machine code (meaning that the flow of machine code should resemble the flow of C/C++ code) and that compiler developers want to focus on the language spec and regard Undefined Behavior as, well, undefined.
The following blog post was rather eye-opening for me, making a fair point for both sides of the argument:
Posted Jan 23, 2024 16:54 UTC (Tue)
by adobriyan (subscriber, #30858)
[Link] (2 responses)
typedef int(*F)(void);
I share the sentiment in spirit though.
Posted Jan 23, 2024 17:13 UTC (Tue)
by adobriyan (subscriber, #30858)
[Link] (1 responses)
Ha-ha, if there are 2 functions which initialise g_F then clang doesn't know which one to use and emits correct code.
Posted Jan 23, 2024 17:37 UTC (Tue)
by farnz (subscriber, #17727)
[Link]
It also emits correct code if only one function initialises g_f; in the event that g_f is uninitialized, the C standard and the C++ standard both agree that the source can take any meaning the compiler chooses. Which includes meanings you didn't intend as well as meanings you did intent.
Posted Jan 23, 2024 20:24 UTC (Tue)
by khim (subscriber, #9252)
[Link] (2 responses)
It would have been great if you would have actually picked some explanation that is factually correct. Because explanation on that link talks about how You program may include another separately compiled file which would call For this program
Posted Jan 24, 2024 5:10 UTC (Wed)
by ghodgkins (subscriber, #157257)
[Link]
In practice, gcc at least does not omit NeverCalled by default. It does, however, if you use the set of flags described in this Stack Overflow post: https://stackoverflow.com/questions/6687630/how-to-remove...
However, if you link against a shared library that calls NeverCalled as an extern symbol (and keep the above flags), it will not be omitted from the output, and the shared library will call NeverCalled correctly. All verified on gcc 11.4.
In summary, the linker does have fairly definitive knowledge of whether NeverCalled is used if the output target is an executable, and it can use this knowledge to omit it if the correct flags are passed.
Posted Jan 24, 2024 10:13 UTC (Wed)
by khim (subscriber, #9252)
[Link]
Author very clearly investigated the assembler output as difference between At this point How is that relevant when work of the compiler is investigated? Linker follows entirely different rules, they may not be 100% aligned with C or C++ standard.
Posted Jan 23, 2024 17:33 UTC (Tue)
by atnot (subscriber, #124910)
[Link] (4 responses)
You curse at the compiler developers and demand they make your code do what you meant and not what you said. They explain that's not how things work and you become enlightened, realizing that the C language is not what you thought it was. Undefined behavior is not the issue, but in fact the lack of guardrails that make it easy to invoke! There was never a conspiracy against you, the results of successive optimizations are just really hard to predict! You yourself just made this mistake in a language you thought you knew well, so maybe buffer overflows aren't just a skill issue after all! We can look to modern lamguage design for solutions! I wake up from my dream.
Posted Jan 24, 2024 20:04 UTC (Wed)
by ballombe (subscriber, #9523)
[Link] (2 responses)
But C was invented to be that way by Dennis Ritchie!
There were system-defined behaviors, but not undefined behaviors.
It is afterward that standardization bodies added undefined behavior to allow portability to non-UNIX system and in an ill-advised attempt to be as fast as FORTRAN on some benchmark without adding more datatype (which never quite succeeded...).
Posted Jan 24, 2024 21:55 UTC (Wed)
by atnot (subscriber, #124910)
[Link]
This is probably trivially true in the sense that "C" was just what the original C compiler did and the original compiler was too primitive to do any sort of code analysis, sure. But that's not really a useful statement. It's not what C has been for decades.
> It is afterward that standardization bodies added undefined behavior to allow portability to non-UNIX system and in an ill-advised attempt to be as fast as FORTRAN on some benchmark
You make it sound like this was a grave unforced error but it really isn't. As soon as you do any sort of optimization you need to decide on an abstract machine that you validate your optimizations against. With a language where it is semantically valid to conjure pointers out of thin air anywhere, write to them, call them as a function, it's impossible to do any sort of analysis or optimization at all. That's what no undefined behavior means. This was already untenable before C was even standardized, even before performance became pretty much the only reason to use it.
So yes, C is not the language you think it is
Posted Jan 24, 2024 22:45 UTC (Wed)
by khim (subscriber, #9252)
[Link]
C was not invented. It evolved. From simple autocode which had no specification at all. That's the issue. Nope. There were plenty of undocumented behaviors and no one knew for sure which ones were “undocumented features” and which were “obvious bugs”. Everyone had an opinion, no one knew for certain. Not even remotely close. Yes, there were some who pushed for some definitions which would allow one to write fast compiler, but the main problem was to create some definition which would be usable for anything at all. They need something that can be used to answer a very simple question: this sequence of character… is it something that should produce some kind of predictable result or not? And if the result is predictable then what is it? Because C was never “invented” it was hard to write rules which would describe what C program even is, but C committee succeeded. Except they wanted to ensure that most, if not all, compilers that claimed that they are C compilers would still be compliant (if, maybe, with some small fixes). But to do that they placed a lot if limitations on what C program shouldn't do… only many of these rules were only needed by some few compilers, not the majority. And that is why these rules were, mostly, ignored by C users: their “advanced” compilers accepted their “correct” programs, why would they worry? But said rules were, of course, embraced by C compiler developers: they finally had an idea what C program is! That's really cool! And very much needed! Only C users continued to be unaware of what is happened till many years later. When C compilers started to actually require that C programs would be, you know, C programs… it was just too late. C users firmly believed that they are right since they wrote C programs like they did for decades. And C compiler developers also believed they are right since they had that language definition which explained that certain things that C users do were “never” permitted in the first place… and that definition also existed for decades… why shouldn't they used that definition? And that's why we are at the dead end: when groups of developers have such an awfully different opinions it's hard to do anything. But C compilers were never actually forgiving (like “we code for the hardware” folks like to think) they were just primitive. They never had any other language definitions except for what they actually had in the C standard. Straight from the horse's mouth: That's something Ritchie actually accepted, but there were many more. The whole thing, ultimately, was an exercise in applying worse is better principle at large and see how long and how much can you stretch it. It worked surprisingly well, but like in any other industry we have arrived at the end of that ability to produce something working without adequate regulations and liability.
Posted Jan 29, 2024 5:34 UTC (Mon)
by yoduh (subscriber, #38527)
[Link]
Posted Jan 23, 2024 17:34 UTC (Tue)
by make (subscriber, #62794)
[Link] (11 responses)
I disagree with your opinion: yes, C++ has footguns (so does C), but C++ also offers tools that help avoid problems that are hard to avoid with C. Having these tools would make the kernel less fragile and more stable.
And know what, some of these C++ tools are actually used by the kernel, disguised as GNU C extensions, wrapped in obscure preprocessor macros. I say: if you decide to use C++ features, use standard C++ instead of non-standard C language extensions.
(It is okay to have a different opinion, of course. I guess a lot of kernel developers share your opinion and prefer C-with-GNU-extensions over a standard C++ subset.)
Posted Jan 23, 2024 19:45 UTC (Tue)
by khim (subscriber, #9252)
[Link] (10 responses)
Nope. And who would decide which “subset” is fine and which “subset” is not fine? Linux developers just understandably reason that it's much better to deal with known devil rather then spend insane amount of time arguing what exactly should be permitted and what shouldn't be permitted in “their” C++ subset. Note that even you talk about “C++ subset”, not “C++ as whole”. Because you know there are some pretty dark corners of C++ which nobody is sure about (e.g. if you specify fields in the initialization of struct in one order and then specify initializers in a different order… what happens?… and if some of these fields are references?…) and in a project where significant proportions of contributors only ever submit one change and then go away… it just wouldn't work. The question is how to enforce that and keep only these C++ features that are beneficial to kernel development are available in kernel and not all the crazy things that C++ also includes out of it. With C++ features that are also GNU C extensions situation is simple: don't enable C++ and you are done. With “standard C++”? How would that work?
Posted Jan 23, 2024 19:51 UTC (Tue)
by mb (subscriber, #50428)
[Link] (9 responses)
A subset would have to be developed and documented properly. That doesn't fall out of the sky. It's real work.
>that it's much better to deal with known devil
That's not better. C is not a known devil. It's an unpredictable time bomb mess with UB lurking at every corner trying to shoot you.
>what happens?
I don't know. Forbid it. Trivial solution.
>The question is how to enforce that
Review and checker scripts.
Posted Jan 23, 2024 20:41 UTC (Tue)
by khim (subscriber, #9252)
[Link] (7 responses)
True. Except that “trivial solution” has a cost. Do you know what you did just now? No? I'll tell you: you have just added another UB to the list which already includes hundreds of them. And then asked humans (reviewers) to look out for these and avoid these.
Now let's go back to your main complaint: So these two hundred plus C UBs are annoying for you. And your solution is… to add more UBs? How would that help? You know the saying: we can solve any problem by introducing an extra level of indirection, except for the problem of too many levels of indirection, right? Similarly with language design: you can solve any problem with a language design with “forbid it” trivial solution — except for the “too many UBs” problem and as you, youself, said: that's the main problem of C (and C++ is even worse). C can be parsed, at least. That's impossible with C++ This makes all these linters much harder to write and less efficient with C++.
Posted Jan 23, 2024 20:49 UTC (Tue)
by mb (subscriber, #50428)
[Link] (6 responses)
No. That's obviously not true.
>impossible with C++
Oh. That's why there isn't one C++ program in the world. It cannot be parsed!
Posted Jan 23, 2024 20:54 UTC (Tue)
by khim (subscriber, #9252)
[Link] (5 responses)
That's just simply definition of UB: some syntactically correct construct that correct program shouldn't include. You have just expanded that list. Means you have expanded list of what you consider UB. Again failure of logic: you couldn't create a tool that would parse all valid programs that it doesn't mean that you couldn't create something that would parse some valid programs. Only different tools (and different compilers) wouldn't agree on what they accept… and yes, that's another (and quite real!) problem with C++. Note that this issue is also a problem for Rust, but Rust tries to mitigate that by making compiler be your linter. C++ is just hopeless.
Posted Jan 24, 2024 6:29 UTC (Wed)
by NYKevin (subscriber, #129325)
[Link] (4 responses)
I'm sorry, but this is nonsense. UB is defined by the C and C++ standards (or whatever language you are using, such as unsafe Rust). Putting "don't do that" in a style guide is in no way equivalent to defining a new instance of UB. It does not cause nasal demons or whatever the metaphor du jour is, it is not assumed by the compiler under the as-if rule, etc. At most, it causes the linter to yell at you, and that's assuming you've bothered to configure such linting in the first place.
Posted Jan 24, 2024 10:04 UTC (Wed)
by khim (subscriber, #9252)
[Link] (3 responses)
Nope. But have you looked on specific of what I'm asking, hmm? I'll repeat: Putting fields in different order than they are declared in a struct is something flat out forbidden in C++20, but very much allowed in C99. And Linux kernel uses that flexibility. It very much does cause them: compilers miscompile such code if references are involved (differently on different optimization levels, because, hey, it's not something either C99 or C++20 allows: C++20 demands initializers in order, C99 doesn't have references in language). How is that not UB? Nope.
Posted Jan 24, 2024 19:19 UTC (Wed)
by mb (subscriber, #50428)
[Link] (2 responses)
>C++20 demands initializers in order
Yeah. So? That is totally fine and easy to diagnose. Last time when I wrote C++, which is many years ago, the compiler warned about that. There is no way you can possibly miss that. And it's trivial to abort the build when that occurs.
>How is that not UB?
Nobody said that.
And nobody wants to allow this kind of UB and it's easy to avoid it.
Posted Jan 24, 2024 20:18 UTC (Wed)
by khim (subscriber, #9252)
[Link] (1 responses)
Easy to diagnose doesn't mean easy to fix. These are certain structures (including in public API) where order of fields is different on different architectures. In C99 that was never a problem. In C++ it is a problem. Except if you disabled warning because it was flooding your build log with useless messages. See above. It's not easy to avoid it. Not in a project with millions lines of code and 30+ years of history. Heck, even in Android there are lots of such warnings! And that's not a project which was written in C and then switched to C++. With Linux kernel it would be worse, much worse.
Posted Jan 24, 2024 21:40 UTC (Wed)
by mb (subscriber, #50428)
[Link]
Nobody said that.
>Except if you disabled warning
This is ridiculous. Please stop it.
>See above. It's not easy to avoid it. Not in a project with millions lines of code and 30+ years of history.
None of these lines will be compiled with a C++ compiler.
You are making things up that nobody suggested.
Posted Jan 23, 2024 22:07 UTC (Tue)
by Wol (subscriber, #4433)
[Link]
The problem with "trivial" is it doesn't mean what most people think. Fermat's last theorem is trivial. "Life, the Universe, and Everything" is trivial.
"Trivial" means "if you follow the rules you'll get your answer". It has absolutely nothing to say about how long that answer will take - and THAT is your problem.
I don't want a couple of noughts added to linux's development time because someone thought they'd add a few "trivial" rules ...
Cheers,
Posted Jan 23, 2024 14:44 UTC (Tue)
by corbet (editor, #1)
[Link] (10 responses)
Posted Jan 23, 2024 20:15 UTC (Tue)
by make (subscriber, #62794)
[Link] (9 responses)
Posted Jan 23, 2024 22:37 UTC (Tue)
by ms-tg (subscriber, #89231)
[Link] (7 responses)
I for one would value an LWN follow up simply interviewing Linus specifically about his 2024 reflections on that 2007communication (and NOT about C++ itself).
From previous reporting here, my understanding is that Linus would not make that same communication today — would love to get some reporting on what he’d write instead? And maybe what the response would be if someone else wrote that today, etc?
Posted Jan 23, 2024 22:43 UTC (Tue)
by make (subscriber, #62794)
[Link] (6 responses)
Posted Jan 24, 2024 9:13 UTC (Wed)
by matthias (subscriber, #94967)
[Link] (5 responses)
Posted Jan 24, 2024 9:40 UTC (Wed)
by make (subscriber, #62794)
[Link] (4 responses)
While Rust and C++ provide many of the same advantages over C, the discussion about allowing them in the kernel is different. The discussion about C++ was poisoned by Linus, who unambiguously stated he would not allow C++, with insults and arguments on a level I'm not comfortable with. Rust started with no such ballast.
Agree, the Rust people did not know whether they'd succeed, because there was no decision. But that decision (for the wrong reasons) already exists for C++.
Posted Jan 24, 2024 10:33 UTC (Wed)
by Wol (subscriber, #4433)
[Link]
Rust also started with the people who control the language stating that it was their aim to get it in the kernel, and as such (a) it was intended to be a low-level language, and (b) if there were any pain points, the people who COULD change the language INTENDED to change the language.
With C++ the three groups of people who (a) define the language, (b) write the compiler(s), and (c) want to get it in the kernel, are pretty disjoint and communication between them often appears to resemble shouting at a brick wall.
Linus is a pragmatist. He looks at the Rust people and thinks "if I find a problem, they will be motivated to solve it". He looks at C++ and thinks "if I find a problem, we'll probably spend years finger-pointing and buck-passing". What language would YOU rather work with.
Cheers,
Posted Jan 24, 2024 10:37 UTC (Wed)
by matthias (subscriber, #94967)
[Link] (2 responses)
The insults and bad arguments are very unfortunate. But this was how Linus at that time reacted to all things he did not like. I think that these insults and arguments were a (bad) reaction to the proposal of a language that was not suited at that time and not the primary reason for the rejection. And obviously the precedent makes the stand for C++ harder. It was already proposed once and rejected. So it is much harder to convince that the language (which in most eyes already failed once) is now a good choice. Maybe the C++ people should have waited for their language to mature before trying to get it into the kernel.
I do not think that C++ has a realistic chance to go into the kernel. Not because of Linus' rant from almost 2 decades ago (which was typical for him at that time), but because it has not that much to give. Today, it has not only to show advantages over C, but also over Rust. And Rust is better in almost all areas. There is no legacy in Rust requiring UB in many places of the language. It is quite possible to write drivers without unsafe code, once the necessary infrastructure (abstractions for C interfaces) is in place. Also there is a huge commitment from the community that not only pushes in the direction of Linux to get the language included but also pushes to get necessary features to be included in the language - as first class language features, not as a compiler extension outside of the language. How realistic would this be for C++ to get features required (or desired) for the Linux kernel inside the language in a reasonable timeframe?
Posted Jan 24, 2024 11:48 UTC (Wed)
by make (subscriber, #62794)
[Link] (1 responses)
Let's have a look at https://harmful.cat-v.org/software/c++/linus - all the reasons one-by-one, only omitting the pure flamebaits ("YOU are full of bullshit") or pure opinions ("C++ is a horrible language"):
- "STL is [un]stable and [un]portable": If a part of the C++ standard library is deemed unsuitable for the kernel, don't include it in the allowed C++ subset. Just like not all of the Rust standard library is in the allowed Rust subset.
- "Boost is [un]stable and [un]portable": Boost is not C++. This is like saying Rust is bad because some random guy on the internet wrote bad Rust code.
- "inefficient abstracted programming models [...]": This is a problem with all abstractions, even in C and moreso in Rust. You can write C++ in a way that's more robust than C but results in identical machine code, if you know what you're doing. Of course, C++ makes it easier than C to write inefficient code. So does Rust.
- "the only way to do good, efficient, and system-level and portable C++ ends up to limit yourself to all the things that are basically available in C": That is not true. C++ has many desirable features like RAII that have zero runtime cost (compared to the equivalent but more verbose C code). On the other hand, rewriting a driver in Rust adds runtime overhead that cannot be eliminated.
- "limiting your project to C [...] means that you get a lot of programmers that do actually understand low-level issues": This one is elitism; raising the difficulty so less competent people cannot contribute. I don't think that's desirable. Having a language that is easier to use and less error prone is good. It's good to have Rust, and it's good to have C++!
- "the whole C++ exception handling thing is fundamentally broken": Not a fact, just Linus's opinion. But I agree that allowing them in the kernel would open a huge can of worms, and thus exceptions shouldn't be in the allowed C++ subset.
- "any compiler or language that likes to hide things like memory allocations behind your back just isn't a good choice for a kernel": Kernel memory allocations are indeed something that needs extreme care. Some standard library containers like std::vector or std::map imply memory allocations, but this is the same in Rust. If that bothers you, don't use those containers (in either language), or use a suitable allocator (in either language).
- "you can write object-oriented code (useful for filesystems etc) in C": Not actually an argument. C is Turing-complete, you can do anything with it. But that misses the point. The point is that C++ and Rust are simpler and safer, while being just as efficient. Using C++ or Rust instead of C helps avoid bugs.
These are the stated reasons for the decision, and they are either completely invalid or can be used to argue that Rust shouldn't be accepted in the kernel. That is why I say all of the reasons are wrong, and they were already wrong in 2007/2004.
> At that time, C++ was simply not ready to be included in the kernel. Many of these advantages were simply not there, yet.
RAII is the one feature that would alone justify switching anything from C to C++, and has been available in C++ since the 80ies, long before Linus wrote the very first line of Linux/Freax.
Posted Jan 24, 2024 19:19 UTC (Wed)
by Hattifnattar (subscriber, #93737)
[Link]
A lot has changed since 2007. C++ standard changed, C++ community changed, Linus Torvalds has also changed. Kernel itself changed! There are very good reason to have a new discussion on the merits of C++ in 2024. Bringing up posts from 17 years ago is fun, but does not help with having a serious conversation today.
Posted Jan 24, 2024 14:14 UTC (Wed)
by aszs (subscriber, #50252)
[Link]
Posted Jan 23, 2024 16:32 UTC (Tue)
by atnot (subscriber, #124910)
[Link] (6 responses)
For one, almost everyone who uses C++ thinks there is a "good subset", but nobody agrees on what that is. In practice that makes it more of a rhetorical tactic than an actionable proposal. You'd have to spend at least as long litigating what that subset is as it took to get something like Rust into the kernel in the first place. The fewer features you allow, the less convincing the benefits will be; the more you allow, the bigger the outcry will be. It's a tough line to walk.
The argument of incremental adoption is attractive, but all of the benefits rely on extensive use of C++ features in core kernel APIs. What this means in practice is maintaining separate wrappers and bindings in both directions, just like with rust today. That's already contention, I don't think adding a third way to shoot yourself in the foot will be any more popular.
I don't mean to say that there's no possible net benefit to allowing some C++ in the kernel. It's just that I don't really see many people being willing to spend that much energy on getting there.
Posted Jan 23, 2024 17:03 UTC (Tue)
by farnz (subscriber, #17727)
[Link] (5 responses)
As corbet says the issue is not in deciding that a good subset of C++ exists and would be nice to use, but in actually doing the work to show that C++ is worth using in the kernel, and addressing all the detractors who say it's not. People have been willing to do that work for Rust, and it's thus making progress; for C++, there's been discussions on and off for years, but nobody doing the work to show that (a) there's a useful subset of C++ that has definite benefits over using C and (b) that there's contributions you will get in this subset of C++ that will not get made if you ask the authors to redo their work in kernel C.
Posted Jan 23, 2024 17:39 UTC (Tue)
by make (subscriber, #62794)
[Link] (4 responses)
Posted Jan 23, 2024 22:22 UTC (Tue)
by Kamilion (subscriber, #42576)
[Link] (2 responses)
It's now 2024, we have C++20, a laundry list of the broken abstractions have been extracted, and even C++17 is still reasonably sane enough compared to what came before. Many of Linus's arguments still stand, STL was a nightmare nobody could wake from, BOOST is a pile of headaches, and *deity help you* if you have to stare at game engine codebases. And those only typically work 'performantly' on a multithreaded CPU with atomics.
Granted, everyone has those now, and when Linus complained back in 2007, we were just getting into Core 2 Duos.
Posted Jan 23, 2024 22:39 UTC (Tue)
by make (subscriber, #62794)
[Link]
Linus wrote he wants no C++ because he wants to keep C++ people away. That's the problem.
Posted Jan 24, 2024 11:50 UTC (Wed)
by khim (subscriber, #9252)
[Link]
Absolutely not! Both C++17 and C++20 include both nice features and also absolutely horrible mess that was created years ago. That's why everyone talks about “C++ subset”. But “C++ susbset” proposal is very much a problem for the project where lots of code is created by cargo-culting pieces of code found on Google and stack overflow. Yes, there rules that people are enforcing but they may only enforce them after code is already written and after it was turned into something working by people who were talking with writing driver for piece of hardware they have released to much fanfare yesterday. Sure, you may ask developers to change certain aspect of that atrocity that they have wrote, but you couldn't demand that they would change the whole design radically and rewrite literally everything from scratch! And C++ has enough diversity in its features for that to be real danger, while Rust, so far, is much more strict and uniform. And yes, community reaction is important, too, but that's of secondary concern. The biggest concern is that people would want to use certain features like coroutines which (in C++ form) are entirely unsuitable for kernel — and rewriting code based on these is not fun.
Posted Jan 24, 2024 11:53 UTC (Wed)
by farnz (subscriber, #17727)
[Link]
Linus made a clear statement, giving a rationale for his rejection; this is not holy writ handed down that will never be rescinded because it is perfect from day one, rather it's a position statement from Linus setting out exactly why he's opposed to C++ in his projects.
If you think C++ in the kernel makes sense, and you're willing to do more than cheer from the sidelines, then you'd be putting time into convincing Linus that it's worth the effort, and that you can come up with a subset of C++, including enforcement via tooling, that deals with his objections to the language, and that convinces Linus (and other "C is the way" doubters) that they're wrong to be opposed to C++ in its entirety, but that your tooling and subset would be a valuable improvement to the kernel.
On top of that, you ideally need to show that using this subset of C++ will get more high-value contributions than sticking to plain C will get; for example, by rewriting a driver in this subset, and showing similar performance with less code, or finding bugs that are present in the C version but that cannot be written in the C++ version without tools complaining loudly.
Posted Jan 23, 2024 18:41 UTC (Tue)
by mb (subscriber, #50428)
[Link]
So, I think it would be a good idea to adopt a carefully defined subset of C++.
I haven't played with C++ (classes) to Rust ffi, yet.
The rest of the 6.8 merge window
I understand that no devicemapper features where deprecated nor deleted, so this may bé a typo
You are right, that was a silly slip of the fingers; fixed now.
Corrected
The rest of the 6.8 merge window
The rest of the 6.8 merge window
The rest of the 6.8 merge window
> compiling the LoongArch kernel module. It is anticipated that this issue
> will be resolved in the upcoming 18.0.0 release. To prevent user
> confusion arising from broken builds, it is advisable to raise the
> minimum required clang version for LoongArch to 18.0.0.
> LoongArch, you need to unset CONFIG_MODULES and CONFIG_RELOCATABLE to
> avoid build errors. Additionally, if you want a workable kernel, some
> modules should be set as y instead of m if CONFIG_MODULES=n.
The rest of the 6.8 merge window
The rest of the 6.8 merge window
Whenever I hack the Linux kernel, I'm horrified by how fragile everything is (and how many unfixed bugs I discover that would have been prevented by just using C++). It's a miracle that the kernel actually works and is pretty stable.
The rest of the 6.8 merge window
The rest of the 6.8 merge window
C++ compiler and the kernel
https://blog.tchatzigiannakis.com/undefined-behavior-can-...
C++ compiler and the kernel
static F g_f;
static int bad(){asm volatile("int3");return 0;}
void bad_init(){g_f = &bad;}
int main(void){return (*g_f)();}
C++ compiler and the kernel
> static F g_f;
> static int bad(){asm volatile("int3");return 0;}
> void bad_init(){g_f = &bad;}
> int main(void){return (*g_f)();}
C++ compiler and the kernel
> The following blog post was rather eye-opening for me, making a fair point for both sides of the argument: https://blog.tchatzigiannakis.com/undefined-behavior-can-...
C++ compiler and the kernel
NeverCalled
is not removed when it's not needed… because it's very much is needed and couldn't be removed.NeverCalled
from global constructor — and then program would become valid and there would be no UB!gcc
and clang
would behave identically and, indeed, clang
version is more optimal.C++ compiler and the kernel
> Actually, the compiler (linker really) would be free to omit NeverCalled, since the author of the blog post asked it to create an executable, as indicated by their compilation flags, and did not link against any libraries which might include a call to NeverCalled.
C++ compiler and the kernel
string "rm -rf /"
and .asciz "rm -rf /"
in compiler outputs shows (that difference is eliminated if you compile code to binary, then disassemble).NeverCalled
have to be in the output because compiler couldn't have any idea about what happens after linking. But compiler does have the right to assume that program would be valid C++ program and valid C++ program have to call NeverCalled
, somehow.The rest of the 6.8 merge window
The rest of the 6.8 merge window
The rest of the 6.8 merge window
> There were system-defined behaviors, but not undefined behaviors.
> But C was invented to be that way by Dennis Ritchie!
The rest of the 6.8 merge window
K&R C has one important internal contradiction (variadic functions are forbidden, yet printf exists) and one important divergence between rule and reality (common vs. ref/def external data definitions). These contradictions have been an embarrassment to me throughout the years, and resolving them was high on X3J11's agenda. X3J11 did manage to come up with an adequate, if awkward, solution to the first problem. Their solution to the second was the same as mine (make a rule, then issue a blanket license to violate it).
The rest of the 6.8 merge window
The rest of the 6.8 merge window
> Your rethorical question implies something as fact that is actually just your opinion.
The rest of the 6.8 merge window
The rest of the 6.8 merge window
It's just the same as all the other development standards that we have documented.
That's no different than the current situation with kernel-C.
> I don't know. Forbid it. Trivial solution.
The rest of the 6.8 merge window
The rest of the 6.8 merge window
> No. That's obviously not true.
The rest of the 6.8 merge window
The rest of the 6.8 merge window
> Putting "don't do that" in a style guide is in no way equivalent to defining a new instance of UB.
The rest of the 6.8 merge window
e.g. if you specify fields in the initialization of struct in one order and then specify initializers in a different order… what happens?… and if some of these fields are references?…
The rest of the 6.8 merge window
That is obvious.
> That is totally fine and easy to diagnose.
The rest of the 6.8 merge window
The rest of the 6.8 merge window
Nobody suggested that.
It's about new code and carefully C++ compatibility-reviewed code.
The rest of the 6.8 merge window
Wol
"Discussions" only get so far. If there is to be C++ code in the kernel, somebody is going to have to take on a huge amount of work to show that it is viable, convince the detractors, solve the many problems that come up, write documentation, and actually create useful C++ code — all the stuff the Rust folks have done, in other words. So far, I do not see anybody doing that work.
C++
C++
That is why you do not see anybody doing that work.
C++
C++
C++
C++
C++
Wol
C++
C++
C++
C++
The rest of the 6.8 merge window
The rest of the 6.8 merge window
The rest of the 6.8 merge window
The rest of the 6.8 merge window
And C++ exception bubbling *still* remains a sharp edge even in C++20. You call it a childish rant, I call it someone who's honest with himself and others. Bluntly and roughly? Sure. But I'm here to run the code, not rub elbows with the developers. I'll take the blunt but honest guy over the marketeer suit pitching me promises nobody can keep.
The rest of the 6.8 merge window
> It's now 2024, we have C++20, a laundry list of the broken abstractions have been extracted, and even C++17 is still reasonably sane enough compared to what came before.
The rest of the 6.8 merge window
The rest of the 6.8 merge window
The rest of the 6.8 merge window
It would make it more robust.
It would also make it slower to build, though.
But only with one important constraint:
It must not make Rust adoption any harder. That would hurt the robustness in the long term.
Is that really mature enough to work on the same level of being as complicated/easy as C to Rust ffi?