CINXE.COM
LWN.net Weekly Edition for November 21, 2024 [LWN.net]
<!DOCTYPE html> <html lang="en"> <head><title>LWN.net Weekly Edition for November 21, 2024 [LWN.net]</title> <link rel="next" href="/Articles/998146/"/> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8"> <META NAME="robots" CONTENT="noai, noimageai"> <link rel="icon" href="https://static.lwn.net/images/favicon.png" type="image/png"> <link rel="alternate" type="application/rss+xml" title="LWN.net headlines" href="https://lwn.net/headlines/rss"> <link rel="stylesheet" href="/CSS/lwn"> <link rel="stylesheet" href="/CSS/nosub"> <script type="text/javascript">var p="http",d="static";if(document.location.protocol=="https:"){p+="s";d="engine";}var z=document.createElement("script");z.type="text/javascript";z.async=true;z.src=p+"://"+d+".adzerk.net/ados.js";var s=document.getElementsByTagName("script")[0];s.parentNode.insertBefore(z,s);</script> <script type="text/javascript"> var ados_keywords = ados_keywords || []; if( location.protocol=='https:' ) { ados_keywords.push('T:SSL'); } else { ados_keywords.push('T:HTTP'); } var ados = ados || {}; ados.run = ados.run || []; ados.run.push(function() { ados_add_placement(4669, 20979, "azk13321_leaderboard", 4).setZone(16026); ados_add_placement(4669, 20979, "azk93271_right_zone", [5,10,6]).setZone(16027); ados_add_placement(4669, 20979, "azk31017_tracking", 20).setZone(20995); ados_setKeywords(ados_keywords.join(', ')); ados_load(); });</script> </head> <body> <a name="t"></a> <div id="menu"><a href="/"><img src="https://static.lwn.net/images/logo/barepenguin-70.png" class="logo" border="0" alt="LWN.net Logo"> <span class="logo">LWN<br>.net</span> <span class="logobl">News from the source</span></a> <a href="/"><img src="https://static.lwn.net/images/lcorner-ss.png" class="sslogo" border="0" alt="LWN"></a><div class="navmenu-container"> <ul class="navmenu"> <li><a class="navmenu" href="#t"><b>Content</b></a><ul><li><a href="/current/">Weekly Edition</a></li><li><a href="/Archives/">Archives</a></li><li><a href="/Search/">Search</a></li><li><a href="/Kernel/">Kernel</a></li><li><a href="/Security/">Security</a></li><li><a href="/Calendar/">Events calendar</a></li><li><a href="/Comments/unread">Unread comments</a></li><li><hr></li><li><a href="/op/FAQ.lwn">LWN FAQ</a></li><li><a href="/op/AuthorGuide.lwn">Write for us</a></li></ul></li> <li><a class="navmenu" href="#t"><b>Edition</b></a><ul><li><a href="/Articles/998144/">⇒Front page</a></li><li><a href="/Articles/998146/">Brief items</a></li><li><a href="/Articles/998147/">Announcements</a></li><li><a href="/Articles/998144/bigpage">One big page</a></li><li><a href="/Articles/997293/">Previous week</a></li><li><a href="/Articles/998950/">Following week</a></li></ul></li> </ul></div> </div> <!-- menu --> <div class="not-handset" style="margin-left: 10.5em; display: block;"> <div class="not-print"> <div id="azk13321_leaderboard"></div> </div> </div> <div class="topnav-container"> <div class="not-handset"><form action="https://lwn.net/Login/" method="post" name="loginform" class="loginform"> <label><b>User:</b> <input type="text" name="uname" value="" size="8" id="uc" /></label> <label><b>Password:</b> <input type="password" name="pword" size="8" id="pc" /></label> <input type="hidden" name="target" value="/Articles/998144/" /> <input type="submit" name="submit" value="Log in" /></form> | <form action="https://lwn.net/subscribe/" method="post" class="loginform"> <input type="submit" name="submit" value="Subscribe" /> </form> | <form action="https://lwn.net/Login/newaccount" method="post" class="loginform"> <input type="submit" name="submit" value="Register" /> </form> </div> <div class="handset-only"> <a href="/subscribe/"><b>Subscribe</b></a> / <a href="/Login/"><b>Log in</b></a> / <a href="/Login/newaccount"><b>New account</b></a> </div> </div><div class="maincolumn flexcol"> <div class="middlecolumn"> <div class="PageHeadline"> <h1>LWN.net Weekly Edition for November 21, 2024</h1> </div> <div class="ArticleText"> <div class="SummarySection"> <a name="998889"></a><h3 class="SummaryHL"><a href="/Articles/998889/">Welcome to the LWN.net Weekly Edition for November 21, 2024</a></h3> This edition contains the following feature content: <p> <ul class="spacylist"> <li> <a href="/Articles/997850/">RVKMS and Rust KMS bindings</a>: before we can have graphics drivers in Rust, the kernel must provide a set of Rust bindings for its kernel mode setting functionality. <li> <a href="/Articles/998221/">Two approaches to tightening restrictions on loadable modules</a>: control over the symbols exported to loadable kernel modules has been an area of frequent discussion in the kernel community; two sets of patches show that there are still issues to resolve. <li> <a href="/Articles/997563/">Dancing the DMA two-step</a>: a new internal kernel API for high-performance DMA I/O. <li> <a href="/Articles/997959/">Development statistics for 6.12</a>: where the code in the 6.12 kernel came from. <li> <a href="/Articles/997559/">Fedora KDE gets a promotion</a>: there will be a new Fedora edition featuring the KDE desktop. <li> <a href="/Articles/998153/">Book review: Run Your Own Mail Server</a>: email does not have to be left in the hands of a small number of huge providers. </ul> <p> This week's edition also includes these inner pages: <p> <ul class="spacylist"> <li> <a href="/Articles/998146/">Brief items</a>: Brief news items from throughout the community. <li> <a href="/Articles/998147/">Announcements</a>: Newsletters, conferences, security updates, patches, and more. </ul> <p> <b>November 28 is the Thanksgiving holiday</b> in the US; following longstanding tradition, there will be no LWN Weekly Edition that day so that we can focus on food preparation, consumption, and digestion. There will be occasional updates to the site, and we'll be back in full force with the December 5 edition. <p> Please enjoy this week's edition, and, as always, thank you for supporting LWN.net. <p><a href="/Articles/998889/#Comments">Comments (none posted)</a> <p> <a name="997850"></a><h3 class="SummaryHL"><a href="/Articles/997850/">RVKMS and Rust KMS bindings</a></h3> <div class="FeatureByline"> By <b>Jake Edge</b><br>November 20, 2024 <hr> <a href="/Archives/ConferenceByYear/#2024-X.Org_Developers_Conference">XDC</a> </div> <p> At the <a href="https://indico.freedesktop.org/event/6/">2024 X.Org Developers Conference</a> (XDC), Lyude Paul gave a talk on the work she has been doing as part of the <a href="https://gitlab.freedesktop.org/drm/nova">Nova project</a>, which is an <a href="/Articles/990736/">effort build an NVIDIA GPU driver in Rust</a>. She wanted to provide an introduction to <a href="/ml/all/20240930233257.1189730-36-lyude@redhat.com/">RVKMS</a>, which is being used to develop Rust kernel mode setting (KMS) bindings; RVKMS is a port of the <a href="https://docs.kernel.org/gpu/vkms.html">virtual KMS</a> (VKMS) driver to Rust. In addition, she wanted to give her opinion on Rust, and why she thinks it is a "<q>game-changer for the kernel</q>", noting that the reasons are not related to the oft-mentioned, "headline" feature of the language: memory safety. </p> <p> The Nova driver is written in Rust in part because of the lack of a stable firmware ABI for NVIDIA GPU system processors (GSPs). Handling that in C is difficult, Paul said. The inspiration came from the Asahi <a href="/Articles/995383/">driver for Apple GPUs</a>, which uses a similar approach to handle unstable firmware ABIs. In addition, the Nova project can help prove Rust's readiness for the kernel by getting its drivers upstream, which will help make it easier for projects like Asahi get their work upstream as well. </p> <p> Writing a kernel driver for a new device is challenging and takes time. For Nova, there is also a need to develop the Rust bindings for a kernel graphics driver. "<q>Luckily, a lot of this has already been done in Asahi</q>". There are already lots of bindings available, though they are not yet upstream; doing so entails figuring out if there are changes needed in those bindings and getting them accepted into the kernel. </p> <p> The Asahi bindings do not cover kernel mode setting, however, which is surprising; KMS is one of the only parts of that driver that is written in C. So there are no KMS bindings to use for Nova and it is still too early in Nova development to add KMS support to it. On the other hand, though, "<q>KMS is a large enough surface that we wanted to be able to work on this sooner than later, and ideally in parallel to the rest of Nova</q>". </p> <h4>RVKMS</h4> <p> So, while Nova was working toward needing KMS, the team decided that Paul would port a KMS driver to Rust in order to create the necessary bindings. VKMS was chosen because "<q>it's a pretty simple driver, it doesn't require any specific hardware</q>". VKMS "<q>pretends to be a display device</q>"; it also supports CRC generation and <a href="/Articles/704647/">writeback connectors</a>, which can be used for testing. </p> <a href="/Articles/998781/"> <img src="https://static.lwn.net/images/2024/xdc-paul-sm.png" border=0 hspace=5 align="right" alt="[Lyude Paul]" title="Lyude Paul" width=224 height=280> </a> <p> For the Rust port, RVKMS, "<q>it's very early in development, driver-wise; it doesn't do a whole ton yet</q>". At this point it can basically just "<q>register a KMS driver and set up <a href="https://en.wikipedia.org/wiki/Vertical_blanking_interval">VBLANK</a> emulation using high-resolution timers</q>". Eventually, she hopes that the driver will have CRC generation and connector writeback, as well. </p> <p> Even though it is still early in RVKMS development, it has already proved "<q>very useful in making progress with these bindings</q>". Paul said that she tried to anticipate the needs of other KMS drivers, such as i915 and nouveau, and not just focus on RVKMS, when designing the API. Most of her time has been spent on the bindings, rather than RVKMS itself, which is still quite small. </p> <p> There are several goals for the KMS bindings; one is to prevent undefined behavior by using safe code. Another is to make incorrect implementations of the KMS API nearly impossible; "<q>Rust gives us a lot of tools to actually be able to prove that the way things are implemented are correct at compile time.</q>" The API should be ergonomic, as well; preventing mistakes should not make for code that is messier or more difficult to write. The intention is to mostly only support <a href="/Articles/653071/">atomic mode setting</a>, though there will "<q>probably be some basic support for the various legacy helpers</q>" </p> <h4>KMS bindings</h4> <p> The KMS bindings are currently working on top of the direct rendering management (DRM) bindings from Asahi and Nova. Unlike the KMS API in C, the Rust KMS bindings "<q>are mostly in control of the order of operations during device registration</q>". In order to support KMS in a Rust driver, it is only necessary to implement the <tt>kernel::drm::kms::Kms</tt> trait, which "<q>handles calling things in the right order, registering the device, and that sort of thing</q>". </p> <p> Paul then went into a fair amount of detail on the KMS bindings, which I will try to relay, though my graphics and Rust knowledge may not be fully up to the task. The <a href="https://www.youtube.com/watch?v=ckUx3otJ7FU">YouTube video</a> of the talk and her <a href="https://indico.freedesktop.org/event/6/contributions/304/attachments/233/314/RVKMS%20XDC2024.pdf">slides</a> will be of interest to those seeking more information. Background material on the Linux graphics stack can be found in <a href="/Articles/955376/">part one</a> of our two-part series looking at it; for this talk, <a href="/Articles/955708/">part two</a> may be the most relevant piece. The <a href="https://en.wikipedia.org/wiki/Direct_Rendering_Manager">Wikipedia article on DRM</a> and its <a href="https://en.wikipedia.org/wiki/Direct_Rendering_Manager#KMS_device_model">section on the KMS device model</a> may also be useful, especially for some of the terminology. </p> <p> There are two main parts to the <tt>Kms</tt> trait, she said. <tt>mode_config_info()</tt> is used for static information, like minimum and maximum resolution, various cursor capabilities, and others. <tt>create_objects()</tt> provides "<q>access to a special <tt>UnregisteredKmsDevice</tt> type</q>" that can be used to create both static (e.g. "cathode-ray-tube controller" (CRTC), plane) and non-static (e.g. connectors) objects. In the future, hooks for customizing the initial mode setting will likely be added, but those are not needed for the virtual display provided by RVKMS. </p> <p> "<q>One of the neat things</q>" with the bindings is that drivers implementing the <tt>Kms</tt> trait, get a <tt>KmsDriver</tt> trait implemented automatically. That allows KMS-dependent methods to only be available to drivers that actually implement <tt>Kms</tt>. So all of the bindings can just assume that KMS is always present and set up, instead of having run-time checking and adding error paths. </p> <h4>Mode objects</h4> <p> DRM has the concept of a "mode object" that is exposed to user space through an object ID. Mode objects can have a reference count and be created at any time, or not have a reference count, but those can only be created before driver registration. The <tt>ModeObject</tt> trait is used to represent them. Reference-counted objects fit in nicely with Rust lifetime requirements; an <tt>RcModeObject</tt> trait is used for those to reduce the reference-counting boilerplate needed. </p> <p> Static objects, such as CRTCs and planes, typically share the lifetime of a device and are more challenging to handle because that does not easily map to Rust lifetimes. The <tt>StaticModeObject</tt> and <tt>KmsRef</tt> traits are used for those types of objects; <tt>KmsRef</tt> acts as a reference count on the parent device, while allowing access to the static object, which allows owned references to the static objects. </p> <p> Implementing CRTCs, planes, and other components of that sort turned out to be "<q>a bit more complicated than one might expect</q>", she said. Most drivers do not use the DRM structures unmodified, and instead embed them into driver-private structures; for example, in VKMS, the <tt>vkms_crtc</tt> structure embeds <tt>drm_crtc</tt>. They contain and track driver-private information, including display state and static information. Drivers often have multiple subclasses of these types of objects; for example, both i915 and nouveau have multiple types of connectors, encoders, and others. </p> <p> It turns out that "<q>this is not the first time we've had to do something like this</q>"; Asahi had to do something similar for its <a href="https://en.wikipedia.org/wiki/Direct_Rendering_Manager#Graphics_Execution_Manager">Graphics Execution Manager</a> (GEM) support. In GEM infrastructure, this type of subclassing, where driver-private data is maintained with the object, is common. The needs for KMS subclassing are more variable than for GEM, because the technique is used more widely, but the Asahi work provided a good starting point, she said. </p> <p> In the KMS bindings, there are traits for the different object types, such as <tt>DriverCrtc</tt> and <tt>DriverEncoder</tt>; drivers can have multiple implementations of them as needed. Driver data can be stored in the objects either by passing immutable data to the constructor or at any other point using <a href="https://doc.rust-lang.org/nomicon/send-and-sync.html">send and sync containers</a>. KMS drivers typically switch between the common representation (e.g. <tt>drm_crtc</tt>) and the driver-specific one (<tt>vkms_crtc</tt>), which is also possible with the KMS Rust bindings. There are some operations that should apply to all instances of the class and others that are only for the specific subclass. So there is a "<q>fully-typed interface</q>" that provides access to the private data and the common DRM methods and an opaque interface that only provides access to the common methods. </p> <p> The same mechanism is used for atomic states, with fully-typed and opaque interfaces, which can be switched between at run time. If access to the private data is needed, objects can be fallibly converted to fully-typed. That required support for consistent <a href="https://en.wikipedia.org/wiki/Virtual_method_table">vtable</a> memory locations, "<q>which is not something that Rust has by default</q>", since constants are normally inlined, rather than stored as static data. A Rust macro (<tt>#[unique]</tt>) was added to make that work. </p> <h4>Atomic commits</h4> <p> "<q>Things diverge a bit</q>" for atomic commits due to Rust's requirements. The Rust data-aliasing rules allow having an infinite number of immutable references to an object or a single mutable reference at any given time. If the atomic callbacks for checking, updating, and the like only affected the object they were associated with, it would be easy to handle, but that is not the case. The callbacks often iterate through the state of other objects, not just the one that the callback belongs to. </p> <p> She originally started implementing the callbacks using just references, but that did not really work at all. Instead, she took inspiration from <a href="https://doc.rust-lang.org/beta/book/ch15-05-interior-mutability.html"><tt>RefCell</tt></a>, which is a "<q>Rust API for handling situations where the data-aliasing rules aren't exactly ideal</q>". Mutable and immutable borrows still exist, but they are checked at run time rather than compile time. </p> <p> When working with the atomic state, most of the code will use the <tt>AtomicStateMutator</tt> container object, which is a wrapper around an <tt>AtomicState</tt> object. There are always immutable references to the container available, and it manages handing out borrows for callbacks that want to examine or change the state. There can only be a single borrow for each state, but a callback can hold borrows for multiple states. Borrowing is fallible, but the interface is meant to be ergonomic; for example, callbacks are made with a pre-borrowed state, so that the callback does not need to obtain it. </p> <p> In order to enforce the order of operations and protect states from mutation once they are made visible outside of the atomic commit, the bindings use the <a href="https://docs.rs/typestate/latest/typestate/">typestate</a> pattern. This is a feature that is not unique to Rust, but is not common in other languages; "<q>Rust generally makes it a lot easier to work with than other languages</q>". It allows the bindings to "<q>encode the run-time state of something into compile-time state</q>"; the idea is that the object is represented by a different type at every stage of its lifetime. It provides "<q>a very powerful tool to actually enforce API correctness</q>", Paul said. </p> <p> For example, <tt>AtomicCommitTail</tt> is an <tt>AtomicState</tt> wrapper that lets the driver developer control the order in which commits are executed. It does so mostly by using tokens for each step of the process; the tokens prove that a certain prerequisite has been done. The checking is done at compile time and "<q>it lets you make it impossible to write an incomplete <tt>atomic_commit_tail()</tt> [callback] that actually compiles</q>". The code has to "<q>perform every step and you have to perform them in the correct order, otherwise the code just doesn't compile</q>". </p> <p> KMS drivers have lots of optional features, she said; for example, VBLANK is used everywhere to some extent, but some hardware does not have a VBLANK interrupt, so it must be emulated in the DRM core. The Rust bindings can use traits to only allow drivers that implement VBLANK to access the appropriate methods; other drivers will not be able to call those methods. If it implements the <tt>DriverCrtcVblank</tt> trait, it will have access to the VBLANK-exclusive methods; that pattern can be extended for other optional pieces of functionality. </p> <p> Paul closed the first part of her talk with thanks to various people and groups who have helped make RVKMS and the KMS bindings possible: the Asahi project, Maíra Canal, and her co-workers at Red Hat working on Nova. From there, she moved on to talk about her experience with Rust. </p> <h4>Rust experiences</h4> <p> "<q>I won't be talking about memory safety</q>", she said; one of the big mistakes made when people are trying to advocate for Rust is to entirely focus on memory safety. Kernel developers already know that C is unsafe, so pushing hard on the memory-safety point often sounds like the Rust advocates are talking down to the kernel developers. That is one of the reasons that she avoided looking at Rust for years. Instead, she believes that there are more compelling arguments for bringing Rust to the kernel. </p> <p> "<q>Rust can be a kernel maintainer</q>"; a huge part of being a maintainer is to stop bad patterns in the code. That is time-consuming, and requires constantly re-explaining problems, while hoping nothing important was missed. "<q>It can make you snippy; it can burn through your motivation</q>". </p> <p> Rust can help with that, because it provides a lot of tools to enforce code patterns that would have needed to be corrected over email. It is "<q>a lot more capable than anything we were really ever able to do in C</q>". The uses of the typestate pattern are a good example of that; they have little, usually no, run-time cost. There is an upfront cost to Rust, in learning the language and in rethinking how code is written to fit into the new model, but "<q>the potential for saving time long term is kind of astounding</q>". </p> <p> People often wonder about how to work with unsafe code, but its presence does not really change much in her experience. For one thing, unsafe code also acts as an enforcement tool; a "safety contract" must be present in the comments for unsafe code or the compiler will complain. That requires those writing unsafe code to think about and document why and how they are violating the language invariants, which gives reviewers and maintainers something to verify. Unsafe acts as a marker for a place where more scrutiny is needed. </p> "<q>It's sort of wild what the end result of this is</q>"; when writing RVKMS, she spent almost no time debugging: around 24 hours over a few months of development. Writing drivers in C has always been a loop of adding a bunch of code, then spending a day or more debugging problems of various sorts (missed null checks, forgotten initialization, thread-safety issues, etc.), and going back to adding code. That is not how things go with Rust; "<q>if things compile, a lot of times it will actually work, which is a very weird concept and is almost unbelievable until you've actually dealt with it yourself</q>". </p> <p> Before Paul started working with Rust, she was put off by a lot of the patterns used, such as a lack of null, having to always handle option returns, and "<q>tons of types, that sounds kind of like a nightmare</q>". It turns out that "<q>Rust is ergonomic enough</q>" that you end up not really thinking about those things once a set of bindings has been developed. Much of the time, it also "<q>almost feels obvious what the right design is</q>". Most of the Rust constructs have lots of shortcuts for making them "<q>as legible and simple as possible</q>". Once you get past the design stage, you rarely need to think about all of the different types; "<q>a lot of the time, the language just sort of handles it for you</q>". </p> <p> She is not a fan of comparisons to C++, in part because "<q>Rust is kind of a shockingly small language</q>". It is definitely complicated and difficult to "<q>wrap your head around at first</q>", but its scope is limited, unlike C++ and other languages, which feel more like a framework than a language, she said. The Rust standard library is built around the "keep it simple, stupid" (KISS) philosophy, but it is also constantly being iterated on to make it easier to use, while not sacrificing compatibility. Once you get used to the Rust way of doing things, the correct way to do something generally feels like the obvious way to do it as well. </p> <p> She concluded her talk with a question: "<q>would you rather repeat yourself on the mailing list a million times</q>" to stop the same mistakes, "<q>or would you rather just have the compiler do it?</q>" She suggested: "<q>Give Rust a try</q>". </p> <h4>Q&A</h4> <p> An audience member asked about how the Rust code would fare in the face of changes to the DRM API in the kernel. Paul said that refactoring Rust code "<q>tends to be very easy, even with a lot of subtly more complicated changes than you might have to work around in C</q>". It is not free, of course, but refactoring in Rust is not any harder than it is for C. </p> <p> Another question was about Rust development finding problems in the existing C APIs and code; Paul said that has happened and she thinks Rust is helpful in that regard because it forces people to clearly think things through. DRM, though, has been pretty well thought-out, she said, so most of what she has seen has been elsewhere in the kernel; in the response to a separate question, she reiterated that DRM was never really an impediment to the Rust work, in part because it is so well designed and documented. </p> <p> Adding functionality to DRM using Rust was also asked about; does it make sense to do so? Paul said that it would make sense because Rust forces the developer to think about things up front, rather than to just get something working quickly and deal with locking or other problems as they arise. That leads to the "if it compiles, it will likely work" nature of Rust code. But, calling Rust from C is difficult, at least for now, so that would limit the ability to use any new Rust features from existing C drivers and other code. </p> <p> Another question was about getting started today on a KMS driver; would she suggest doing that in C or in Rust? For now, she would recommend C, though that may change eventually. The problem is that there are a lot of missing bindings at this point and whenever she adds functionality to RVKMS, she ends up adding more bindings. Designing bindings requires more overall knowledge of DRM and other KMS drivers in addition to Rust itself. Once most of the bindings are available, though, starting out with Rust will be a reasonable approach. </p> <p> The last question was about compile time, which is often a problem for larger Rust projects. Paul said that she was "<q>actually surprisingly happy</q>" with the compile time at this point, but it is probably too early to make that determination. Once more Rust code is added into the mix, that will be when the compile-time problem pops up. </p> <p> [ I would like to thank LWN's travel sponsor, the Linux Foundation, for travel assistance to Montreal for XDC. ] </p> <p><a href="/Articles/997850/#Comments">Comments (1 posted)</a> <p> <a name="998221"></a><h3 class="SummaryHL"><a href="/Articles/998221/">Two approaches to tightening restrictions on loadable modules</a></h3> <div class="FeatureByline"> By <b>Jonathan Corbet</b><br>November 15, 2024 </div> The kernel's loadable-module facility allows code to be loaded into (and sometimes removed from) a running kernel. Among other things, loadable modules make it possible to run a kernel with only the subsystems needed for the system's hardware and workload. Loadable modules can also make it easy for out-of-tree code to access parts of the kernel that developers would prefer to keep private; this has led to <a href="/Kernel/Index/#Modules-Exported_symbols">many discussions</a> in the past. The topic has returned to the kernel's mailing lists with two different patch sets aimed at further tightening the restrictions applied to loadable modules. <p> When the static kernel image is linked, references to symbols (the names of functions and data structures) are resolved using the entire global namespace. Loading a module also involves a linking step, but modules do not have access to the full namespace; instead, they can only access symbols that have been explicitly exported to them. There are two sets of exported symbols: those that are available to any loadable module, and those that are only available to modules that declare a GPL-compatible license. Access to symbols is the primary means by which the capabilities of loadable modules are limited, so it is not surprising that both patch sets make changes to that mechanism. <p> <h4>Restricted namespaces</h4> <p> For most of the kernel's existence, there has been a single namespace to hold all of the symbols available to a loadable module; that namespace only contains the GPL-restricted symbols if the module is appropriately licensed. In 2018, the kernel gained <a href="/Articles/760045/">a symbol namespacing capability</a> that can segregate some symbols and restrict their availability to modules that explicitly import the relevant namespace. This feature was meant to (among other things) make abuses (modules accessing symbols that they should not) more evident, but it has no access-control capability; symbols can still be made available just by importing the namespace that contains them. <p> There has long been a wish, though, for the ability to export symbols for use by a specific module, but no others. <a href="/ml/all/20241106190240.GR10375@noisy.programming.kicks-ass.net">This patch</a> from Peter Zijlstra adds that feature. In current kernels, a symbol is exported into a specific namespace (call it <tt>foo</tt>) with a declaration like: <p> <pre> EXPORT_SYMBOL_NS_GPL(symbol_name, foo); </pre> <p> Any module that contains a line like: <p> <pre> MODULE_IMPORT_NS(foo); </pre> <p> can then access the symbols exported into that namespace. Zijlstra's patch adds a tweak to the export declaration. To export a symbol that is <i>only</i> available within the module called <tt>foo</tt>, the declaration would be: <p> <pre> EXPORT_SYMBOL_NS_GPL(symbol_name, MODULE_foo); </pre> <p> This creates a namespace with a couple of special properties. When a module named <tt>foo</tt> is loaded, this namespace will be implicitly imported; there is no need for a <tt>MODULE_IMPORT_NS()</tt> declaration. And, in fact, any attempt to import a namespace whose name starts with <tt>MODULE_</tt> will be blocked. The end result is that the symbol is available to <tt>foo</tt>, but to no other module. <p> In the discussion, nobody argued against the addition of this capability. There were a few thoughts on the syntax. Luis Chamberlain, the module-loader maintainer, <a href="/ml/all/Zyv-yxClglfwvmUa@bombadil.infradead.org/">suggested</a> that a separate <tt>EXPORT_SYMBOL_GPL_FOR()</tt> syntax might be preferable to the <tt>MODULE_</tt> convention; he also said that it would be useful to be able to export symbols to more than one module. <p> Masahiro Yamada, the maintainer of the kernel's build system, <a href="/ml/all/CAK7LNASDnB86Ds_dqBTxfHi=OfTXqu66U3v+4M_OEzKiK5Skdw@mail.gmail.com">said</a> that it would be better for the namespace name to be a C string rather than a bare name. That would eliminate some ambiguities within the kernel code; it would also be possible for that string to be a comma-separated list of target modules. That would be a big change, as was demonstrated when Zijlstra <a href="/ml/all/20241107125044.GB38786@noisy.programming.kicks-ass.net">took a stab at it</a>: the resulting patch touched 847 files. <p> It seems likely that the quoted-string approach will be favored going forward, though. Zijlstra has put together <a href="/ml/all/20241107152749.GA38972@noisy.programming.kicks-ass.net/">a version of the patch</a> that supports exporting to multiple modules using that syntax. It "<q>seems to work with very limited testing</q>", but has not yet been reposted to the list. The posting <a href="/ml/all/20241115124935.GC22801@noisy.programming.kicks-ass.net">can be expected</a> soon if all goes well, but chances are that this work is a bit too late to make it into the 6.13 kernel release. <p> <h4>When "GPL" is not GPL</h4> <p> Meanwhile, a separate patch is taking a rather different approach to the problem of inappropriate access to symbols by loadable modules. The kernel is licensed under version 2 of the GNU General Public License, and no other. When the Free Software Foundation created version 3 of the GPL, it was made incompatible with version 2; the kernel community declined to switch to the new license, and so cannot accept code that is licensed under GPLv3. So one would not normally expect to see device drivers (or other kernel modules) released under that license. <p> It turns out, though, that <a href="https://www.tuxedocomputers.com/en">Tuxedo Computers</a> maintains <a href="https://gitlab.com/tuxedocomputers/development/packages">a set of device drivers</a> for its hardware, and those drivers are indeed licensed under GPLv3. In the <tt>MODULE_LICENSE()</tt> declaration within those modules, though, the license is claimed to be "GPL". As a result, these modules have access to GPL-only kernel exports, even though they do not have a license that is compatible with the kernel's. <p> This situation has been in the open for some time, but it was only brought to the foreground after <a href="https://fosstodon.org/@kernellogger/113423314337991594">this research</a> from Thorsten Leemhuis pulled it all together. Neal Gompa <a href="https://github.com/tuxedocomputers/tuxedo-keyboard/issues/61">pointed it out</a> in 2020 and asked for a relicensing to GPLv2. The discussion has resurfaced a few times since then, but the company has refused to make that change. Earlier this year, Tuxedo's Werner Sembach <a href="https://gitlab.com/tuxedocomputers/development/packages/tuxedo-drivers/-/issues/137#note_1807179414">made the company's position clear</a>: "<q>We do not plan to relicense the tuxedo-drivers project directly as we want to keep control of the upstream pacing</q>". In other words, the incompatible license is a deliberate choice made by the company to keep its drivers out of the mainline until a time of its own choosing. <p> The licensing decision may be a bit strange, but it is certainly within the company's rights. Declaring a compatible license to gain access to restricted symbols is not, though. In response, Uwe Kleine-König has posted <a href="/ml/all/20241114103133.547032-4-ukleinek@kernel.org/">a patch series</a> that explicitly blocks the Tuxedo drivers from accessing GPL-only symbols. With this patch in place, those drivers will no longer load properly into the kernel and will stop working. <p> The response to the patch has been generally (if <a href="/ml/all/20241114131843.0df6a5a2@kf-ir16/">not exclusively</a>) positive. But Sembach, unsurprisingly, <a href="/ml/all/e32e9f5c-3841-41f7-9728-f998f123cc8a@tuxedocomputers.com/">is not a fan</a>. According to him, the situation is the result of understandable confusion: "<q>We ended up in this situation as MODULE_LICENSE("GPL") on its own does not hint at GPL v2, if one is not aware of the license definition table in the documentation</q>". The licensing situation is being worked on, he said, and will eventually be resolved. <p> If the company truly intends to work things out in good faith, it would almost certainly make sense to hold off on explicitly blocking its modules while that work proceeds. Given how long this problem has been known, though, and given the company's deliberate use of license incompatibility to retain control over its code, convincing the development community of its good faith may be difficult. That hasn't kept Sembach from trying; he <a href="/ml/all/20241115130139.1244786-1-wse@tuxedocomputers.com">has relicensed</a> some of the modules in question, and promises to change the rest as soon as possible. <p> That is a step in the right direction, but there is no fury that compares to that of a kernel developer who feels lied to about module licensing. Kleine-König has <a href="/ml/all/h5q36ajuzgwf5yrjmqv46x62evifcgoi5imxhcvsv7oxauvxak@sj54oisawqnf">indicated</a> his intent to try to merge the patch during the 6.13 merge window. Then, he said, if the licensing issue is fully resolved, "<q>you have my support to revert the patch under discussion</q>". Whether things will truly go that far is unclear; if Tuxedo is working to resolve the problem quickly, there will probably be little appetite for merging a patch punishing the company in the meantime. It seems unlikely, though, that Tuxedo will attempt this particular trick again, and any others considering it have reason to think again. <p><a href="/Articles/998221/#Comments">Comments (58 posted)</a> <p> <a name="997563"></a><h3 class="SummaryHL"><a href="/Articles/997563/">Dancing the DMA two-step</a></h3> <div class="FeatureByline"> By <b>Jonathan Corbet</b><br>November 14, 2024 </div> Direct memory access (DMA) I/O is simple in concept: a peripheral device moves data directly to or from memory while the CPU is busy doing other things. As is so often the case, DMA is rather more complicated in practice, and the kernel has developed a complicated internal API to support it. It turns out that the DMA API, as it exists now, can affect the performance of some high-bandwidth devices. In an effort to address that problem, Leon Romanovsky is making the API even more complex with <a href="/ml/all/cover.1731244445.git.leon@kernel.org">this patch series</a> adding a new two-step mapping API. <p> <h4>DMA challenges</h4> <p> In the early days, a device driver would initiate a DMA operation by passing the physical address of a memory buffer to the device and telling it to go. There are a number of reasons why things cannot be so simple on current systems, though, including: <p> <ul class="spacylist"> <li> The device may not be able to reach the buffer. ISA devices were limited to 24-bit DMA addresses, for example, so any memory located above that range was inaccessible to those devices. More recently, many devices were still limited to 32-bit addresses, though hopefully that situation has improved over time. If a buffer is out of a device's reach, it must be copied into reachable memory (a practice known as "bounce buffering") before setting up the I/O operation. <li> The combination of memory caching in the CPU and DMA can lead to inconsistent views of the data held in memory — the device cannot see data that exists only in the cache, for example. If not properly managed, cache consistency (or the lack thereof) can lead to data corruption, which is usually deemed to be a bad thing. <li> The buffer involved in a transfer may be scattered throughout physical memory; for larger transfers, it is almost guaranteed to be. The kernel's DMA layer manages the scatter/gather lists ("scatterlists") needed to describe these operations. <li> Modern systems often do not give devices direct access to the physical memory space; instead, that access is managed through an I/O memory-management unit (IOMMU), which creates an independent address space for peripheral devices. Any DMA operation requires setting up a mapping within the IOMMU to allow the device to access the buffer. An IOMMU can make a physically scattered buffer look contiguous to a device. It may also be able to prevent the device from accessing memory outside of the buffer; this capability is necessary to safely allow virtual machines to directly access I/O devices. <li> DMA operations between two peripheral devices (without involving main memory at all) — <a href="/Articles/767281/">P2PDMA</a> — add a whole new level of complexity. </ul> <p> To top it all off, a device driver usually cannot be written with a knowledge of the organization of every system on which it will run, so it must be able to adapt to the DMA-mapping requirements it finds. <p> <!-- middle-ad --> All of this calls out for a kernel layer to abstract the DMA-mapping task and present a uniform interface to device drivers. The kernel <a href="https://docs.kernel.org/core-api/dma-api.html">has such a layer</a>, which has been present in something close to its current form for some years. At the core of this layer is the scatterlist API. As Romanovsky notes in the patch cover letter, though, this API has been showing signs of strain for some time. <p> Scatterlists are used heavily in the DMA API, but they are fundamentally based on the kernel's <tt>page</tt> structure, which describes a single page of memory. That makes scatterlists unable to deal with larger groupings of pages (folios) without splitting them into individual pages. Being based on <tt>struct page</tt> also complicates P2PDMA; since only device memory is involved for those operations, there are no <tt>page</tt> structures to use. Increasingly, I/O operations are already represented in the kernel in a different form (an array of <tt>bio</tt> structures for a block operation, for example), reformatting that information into a scatterlist is mostly unnecessary overhead. So there has been interest in improving or replacing scatterlists for some time; see <a href="/Articles/931943/">the phyr discussion from 2023</a> for example. So far, though, scatterlists have proved resistant to these efforts. <p> <h4>Splitting things up</h4> <p> Romanovsky has set out to create a DMA API that will address many of the complaints about scatterlists while improving performance. The core idea, he says is to "<q>instead split up the DMA API to allow callers to bring their own data structure</q>". The split, in this case, is between the allocation of an I/O virtual address (IOVA) space for an operation and the mapping of memory into that space. This new API is intended to be a supplemental option on high-end systems with IOMMUs; it will not replace the existing DMA API. <p> The first step when using this new API is to allocate a range of IOVA space to be used with the upcoming transfer(s): <p> <pre> bool dma_iova_try_alloc(struct device *dev, struct dma_iova_state *state, phys_addr_t phys, size_t size); </pre> <p> This function will attempt to allocate a <tt>size</tt>-byte IOVA range for use by the given device (<tt>dev</tt>). The <tt>phys</tt> argument only indicates the necessary alignment for this range; for devices that only require page alignment, passing zero will work. The <tt>state</tt> structure must be provided by the caller, but will be completely initialized by this call. <p> If the allocation attempt is successful, this function will return <tt>true</tt> and the physical address of the range (as seen by the device) will be stored in <tt>state.addr</tt>. Otherwise, the return value will be <tt>false</tt>, and the older DMA API must be used instead. Thus, the new API does not enable the removal of scatterlist support from any drivers; it just provides a higher-performance alternative on systems where it is supported. <p> If the allocation is successful, the result is an allocated range of IOVA space that does not yet map to anything. The driver can map ranges of memory into this IOVA area with: <p> <pre> int dma_iova_link(struct device *dev, struct dma_iova_state *state, phys_addr_t phys, size_t offset, size_t size, enum dma_data_direction dir, unsigned long attrs); </pre> <p> Here <tt>dev</tt> is the device that will be performing the I/O (the same one that was used to allocate the IOVA space), <tt>state</tt> is the state structure used to allocate the address range, <tt>phys</tt> is the physical address of the memory range to map, <tt>offset</tt> is the offset into the IOVA range where this memory should be mapped, <tt>size</tt> is the size of the range to be mapped, <tt>dir</tt> describes the I/O direction (whether data is moving to or from the device), and <tt>attrs</tt> holds the optional <a href="https://elixir.bootlin.com/linux/v6.11.6/source/include/linux/dma-mapping.h#L15">attributes</a> that can modify the mapping. The return value will be zero (for success) or a negative error code. <p> Once all of the memory has been mapped, the driver should make a call to: <p> <pre> int dma_iova_sync(struct device *dev, struct dma_iova_state *state, size_t offset, size_t size); </pre> <p> This call will synchronize the I/O translation lookaside buffer (an expensive operation that should only be done once, after the mapping is complete) for the indicated range of the IOVA area. Then the I/O operation can be initiated. <p> Afterward, portions of the IOVA range can be unmapped with: <p> <pre> void dma_iova_unlink(struct device *dev, struct dma_iova_state *state, size_t offset, size_t size, enum dma_data_direction dir, unsigned long attrs); </pre> <p> Once all the mappings have been unlinked, the IOVA can be freed with: <p> <pre> void dma_iova_free(struct device *dev, struct dma_iova_state *state); </pre> <p> Alternatively, a call to: <p> <pre> void dma_iova_destroy(struct device *dev, struct dma_iova_state *state, size_t mapped_len, enum dma_data_direction dir, unsigned long attrs); </pre> <p> will unmap the entire range (up to <tt>mapped_len</tt>), then free the IOVA allocation. <p> In summary, Romanovsky is proposing an API that can be used to map a scattered set of buffers into a single, contiguous IOVA range. There is no need to create a separate scatterlist data structure to represent this operation, and there is no need to use <tt>page</tt> structures to refer to the memory. <h4>Current state</h4> <p> This API has been through a few revisions at this point, and some developers, at least, are happy with it. While the new API provides improved performance for some use cases, Jens Axboe has <a href="/ml/all/3144b6e7-5c80-46d2-8ddc-a71af3c23072@kernel.dk/">observed</a> performance regressions within the block layer that are not yet understood. For now, Romanovsky has <a href="/ml/all/20241031090530.GC7473@unreal/">removed</a> some of the block-layer changes that he deems to be the most likely source of the problem. <p> Robin Murphy has, instead, <a href="/ml/all/3567312e-5942-4037-93dc-587f25f0778c@arm.com/">questioned</a> one of the core assumptions of this API: that there is value in mapping scatter/gather operations into a contiguous IOVA range: <p> <blockquote class="bq"> TBH I doubt there are many actual scatter-gather-capable devices with significant enough limitations to meaningfully benefit from DMA segment combining these days - I've often thought that by now it might be a good idea to turn that behaviour off by default and add an attribute for callers to explicitly request it. </blockquote> <p> Christoph Hellwig <a href="/ml/all/20241104095831.GA28751@lst.de/">responded</a> that devices often perform better with a contiguous IOVA range, even if they are able to handle a severely fragmented one. Jason Gunthorpe <a href="/ml/all/20241105195357.GI35848@ziepe.ca/">agreed</a>, saying that RDMA operations see "<q>big wins</q>" when the IOVA range is contiguous. So it does appear that there is a need for this capability. <p> The patch set seems to have reasonably broad support, and the rate of change appears to be slowing. There are, of course, possible improvements to the API that could be considered; Gunthorpe mentioned better control over alignment in the above-linked message, for example, but those can come later. Romanovsky has <a href="/ml/all/20241114133011.GA606631@unreal">asked</a> that it be merged for 6.13 so that drivers can easily start to use it. While there are no guarantees at this point (and some <a href="/ml/all/20241114163622.GA3121@lst.de">resistance to the idea</a>), it seems possible that the next kernel will include a new, high-performance DMA API. <p><a href="/Articles/997563/#Comments">Comments (none posted)</a> <p> <a name="997959"></a><h3 class="SummaryHL"><a href="/Articles/997959/">Development statistics for 6.12</a></h3> <div class="FeatureByline"> By <b>Jonathan Corbet</b><br>November 18, 2024 </div> Linus Torvalds <a href="/ml/all/CAHk-=wgtGkHshfvaAe_O2ntnFBH3EprNk1juieLmjcF2HBwBgQ@mail.gmail.com/">released the 6.12 kernel</a> on November 17, as expected. This development cycle, the last for 2024, brought 13,344 non-merge changesets into the mainline kernel; that made it a relatively slow cycle from this perspective, but 6.12 includes a long list of significant new features. The time has come to look at where those changes came from, and to look at the year-long LTS cycle as well. <p> The 6.12 kernel included work from 2,074 developers; this is not a record (that is 2,090 in 6.2), but is close. Of those developers, 335 made their first contribution to the kernel during this cycle; that <i>is</i> a record for the Git era (and probably before as well). The most active developers during this cycle were: <p> <blockquote> <table> <tr><th colspan=2 align="center">Most active 6.12 developers</th></tr> <tr><td width="50%" valign="top"> <table cellspacing=3 class="OddEven"> <tr><th colspan=3>By changesets</th></tr> <tr><td>Krzysztof Kozlowski </td><td align="right">225</td><td align="right">1.7%</td></tr> <tr><td>Kent Overstreet </td><td align="right">186</td><td align="right">1.4%</td></tr> <tr><td>Tejun Heo </td><td align="right">131</td><td align="right">1.0%</td></tr> <tr><td>Jinjie Ruan </td><td align="right">123</td><td align="right">0.9%</td></tr> <tr><td>Javier Carrasco </td><td align="right">109</td><td align="right">0.8%</td></tr> <tr><td>Sean Christopherson </td><td align="right">108</td><td align="right">0.8%</td></tr> <tr><td>Andy Shevchenko </td><td align="right">107</td><td align="right">0.8%</td></tr> <tr><td>Takashi Iwai </td><td align="right">106</td><td align="right">0.8%</td></tr> <tr><td>Alex Deucher </td><td align="right">95</td><td align="right">0.7%</td></tr> <tr><td>Nuno Sa </td><td align="right">94</td><td align="right">0.7%</td></tr> <tr><td>Christoph Hellwig </td><td align="right">90</td><td align="right">0.7%</td></tr> <tr><td>Frank Li </td><td align="right">89</td><td align="right">0.7%</td></tr> <tr><td>Jani Nikula </td><td align="right">88</td><td align="right">0.7%</td></tr> <tr><td>Rob Herring </td><td align="right">85</td><td align="right">0.6%</td></tr> <tr><td>Matthew Wilcox </td><td align="right">85</td><td align="right">0.6%</td></tr> <tr><td>Ian Rogers </td><td align="right">83</td><td align="right">0.6%</td></tr> <tr><td>Namhyung Kim </td><td align="right">75</td><td align="right">0.6%</td></tr> <tr><td>Christian Brauner </td><td align="right">74</td><td align="right">0.6%</td></tr> <tr><td>Christophe JAILLET </td><td align="right">73</td><td align="right">0.5%</td></tr> <tr><td>Hongbo Li </td><td align="right">72</td><td align="right">0.5%</td></tr> </table> </td><td width="50%" valign="top"> <table cellspacing=3 class="OddEven"> <tr><th colspan=3>By changed lines</th></tr> <tr><td>Cezary Rojewski </td><td align="right">22850</td><td align="right">3.7%</td></tr> <tr><td>Yevgeny Kliteynik </td><td align="right">17704</td><td align="right">2.8%</td></tr> <tr><td>Samson Tam </td><td align="right">14305</td><td align="right">2.3%</td></tr> <tr><td>Tejun Heo </td><td align="right">14224</td><td align="right">2.3%</td></tr> <tr><td>Herbert Xu </td><td align="right">11867</td><td align="right">1.9%</td></tr> <tr><td>Nikita Shubin </td><td align="right">9270</td><td align="right">1.5%</td></tr> <tr><td>Pavitrakumar M </td><td align="right">8378</td><td align="right">1.3%</td></tr> <tr><td>Philipp Hortmann </td><td align="right">7690</td><td align="right">1.2%</td></tr> <tr><td>Eddie James </td><td align="right">7138</td><td align="right">1.1%</td></tr> <tr><td>Lorenzo Stoakes </td><td align="right">6919</td><td align="right">1.1%</td></tr> <tr><td>Dmitry Torokhov </td><td align="right">6667</td><td align="right">1.1%</td></tr> <tr><td>Alexandre Mergnat </td><td align="right">6385</td><td align="right">1.0%</td></tr> <tr><td>Kent Overstreet </td><td align="right">6309</td><td align="right">1.0%</td></tr> <tr><td>David Howells </td><td align="right">5435</td><td align="right">0.9%</td></tr> <tr><td>Harald Freudenberger </td><td align="right">5124</td><td align="right">0.8%</td></tr> <tr><td>Takashi Iwai </td><td align="right">4922</td><td align="right">0.8%</td></tr> <tr><td>Deven Bowers </td><td align="right">4873</td><td align="right">0.8%</td></tr> <tr><td>Inochi Amaoto </td><td align="right">4739</td><td align="right">0.8%</td></tr> <tr><td>Junfeng Guo </td><td align="right">4503</td><td align="right">0.7%</td></tr> <tr><td>Chuck Lever </td><td align="right">4416</td><td align="right">0.7%</td></tr> </table> </td></tr> </table> </blockquote> <p> Krzysztof Kozlowski continued a long-running effort to refactor low-level device code and devicetree bindings. Kent Overstreet is also working on a long-running project — the effort to stabilize the bcachefs filesystem. Tejun Heo contributed the <a href="/Articles/974387/">extended scheduler class</a>. Jinjie Ruan and Javier Carrasco both contributed a lot of cleanups in the driver subsystem. <p> In the "lines changed" column, Cezary Rojewski removed a number of old audio drivers. Yevgeny Kliteynik added a bunch of functionality to the mlx5 network-interface driver. Samson Tam added some new features to the AMD graphics driver, and Herbert Xu reverted a set of cryptographic-driver patches that were not properly submitted. <p> There were Reviewed-by tags in 48% of the commits merged for 6.12, while just under 10% of the commits in this release included Tested-by tags. The top testers and reviewers this time around were: <p> <blockquote> <table> <tr><th colspan=2 align="center">Test and review credits in 6.12</th></tr> <tr><td width="50%" valign="top"> <table cellspacing=3 class="OddEven"> <tr><th colspan=3>Tested-by</th></tr> <tr><td>Daniel Wheeler </td><td align="right">198</td><td align="right">14.6%</td></tr> <tr><td>Philipp Hortmann </td><td align="right">58</td><td align="right">4.3%</td></tr> <tr><td>Arnaldo Carvalho de Melo </td><td align="right">55</td><td align="right">4.0%</td></tr> <tr><td>Rafal Romanowski </td><td align="right">33</td><td align="right">2.4%</td></tr> <tr><td>Alexander Sverdlin </td><td align="right">30</td><td align="right">2.2%</td></tr> <tr><td>Jonathan Cameron </td><td align="right">25</td><td align="right">1.8%</td></tr> <tr><td>Valentin Schneider </td><td align="right">23</td><td align="right">1.7%</td></tr> <tr><td>Ojaswin Mujoo </td><td align="right">22</td><td align="right">1.6%</td></tr> <tr><td>Alibek Omarov </td><td align="right">20</td><td align="right">1.5%</td></tr> <tr><td>Zi Yan </td><td align="right">19</td><td align="right">1.4%</td></tr> <tr><td>Pucha Himasekhar Reddy </td><td align="right">18</td><td align="right">1.3%</td></tr> <tr><td>Andreas Kemnade </td><td align="right">18</td><td align="right">1.3%</td></tr> <tr><td>Alice Ryhl </td><td align="right">17</td><td align="right">1.3%</td></tr> <tr><td>Björn Töpel </td><td align="right">17</td><td align="right">1.3%</td></tr> </table> </td><td width="50%" valign="top"> <table cellspacing=3 class="OddEven"> <tr><th colspan=3>Reviewed-by</th></tr> <tr><td>Simon Horman </td><td align="right">210</td><td align="right">2.5%</td></tr> <tr><td>Krzysztof Kozlowski </td><td align="right">180</td><td align="right">2.2%</td></tr> <tr><td>Andrew Lunn </td><td align="right">131</td><td align="right">1.6%</td></tr> <tr><td>David Sterba </td><td align="right">116</td><td align="right">1.4%</td></tr> <tr><td>Jan Kara </td><td align="right">109</td><td align="right">1.3%</td></tr> <tr><td>Darrick J. Wong </td><td align="right">99</td><td align="right">1.2%</td></tr> <tr><td>Christoph Hellwig </td><td align="right">98</td><td align="right">1.2%</td></tr> <tr><td>Jeff Layton </td><td align="right">97</td><td align="right">1.2%</td></tr> <tr><td>Josef Bacik </td><td align="right">95</td><td align="right">1.1%</td></tr> <tr><td>Geert Uytterhoeven </td><td align="right">93</td><td align="right">1.1%</td></tr> <tr><td>Jonathan Cameron </td><td align="right">90</td><td align="right">1.1%</td></tr> <tr><td>Rob Herring </td><td align="right">87</td><td align="right">1.0%</td></tr> <tr><td>Andy Shevchenko </td><td align="right">82</td><td align="right">1.0%</td></tr> <tr><td>Konrad Dybcio </td><td align="right">81</td><td align="right">1.0%</td></tr> </table> </td></tr></table> </blockquote> <p> The testing side is dominated, as usual, by people who seem to do that work as their primary job; one exception would be Arnaldo Carvalho de Melo, who tests a lot of <tt>perf</tt> patches as the maintainer before applying them. Simon Horman was the most prolific reviewer this time around, adding his tag to over three network-subsystem patches every day of this development cycle. <p> Work on 6.12 was supported by 218 employers that we were able to identify — a typical number. The most active employers were: <p> <blockquote> <table> <tr><th colspan=2 align="center">Most active 6.12 employers</th></tr> <tr><td width="50%" valign="top"> <table cellspacing=3 class="OddEven"> <tr><th colspan=3>By changesets</th></tr> <tr><td>Intel</td><td align="right">1240</td><td align="right">9.3%</td></tr> <tr><td>(Unknown)</td><td align="right">1173</td><td align="right">8.8%</td></tr> <tr><td>Google</td><td align="right">957</td><td align="right">7.2%</td></tr> <tr><td>AMD</td><td align="right">810</td><td align="right">6.1%</td></tr> <tr><td>Huawei Technologies</td><td align="right">791</td><td align="right">5.9%</td></tr> <tr><td>(None)</td><td align="right">672</td><td align="right">5.0%</td></tr> <tr><td>Red Hat</td><td align="right">651</td><td align="right">4.9%</td></tr> <tr><td>Linaro</td><td align="right">618</td><td align="right">4.6%</td></tr> <tr><td>Meta</td><td align="right">480</td><td align="right">3.6%</td></tr> <tr><td>NVIDIA</td><td align="right">382</td><td align="right">2.9%</td></tr> <tr><td>SUSE</td><td align="right">361</td><td align="right">2.7%</td></tr> <tr><td>Oracle</td><td align="right">262</td><td align="right">2.0%</td></tr> <tr><td>Renesas Electronics</td><td align="right">254</td><td align="right">1.9%</td></tr> <tr><td>IBM</td><td align="right">249</td><td align="right">1.9%</td></tr> <tr><td>Arm</td><td align="right">241</td><td align="right">1.8%</td></tr> <tr><td>NXP Semiconductors</td><td align="right">236</td><td align="right">1.8%</td></tr> <tr><td>(Consultant)</td><td align="right">229</td><td align="right">1.7%</td></tr> <tr><td>Qualcomm</td><td align="right">175</td><td align="right">1.3%</td></tr> <tr><td>Microsoft</td><td align="right">159</td><td align="right">1.2%</td></tr> <tr><td>Linutronix</td><td align="right">140</td><td align="right">1.0%</td></tr> </table> </td><td width="50%" valign="top"> <table cellspacing=3 class="OddEven"> <tr><th colspan=3>By lines changed</th></tr> <tr><td>Intel</td><td align="right">68687</td><td align="right">11.0%</td></tr> <tr><td>(Unknown)</td><td align="right">52196</td><td align="right">8.3%</td></tr> <tr><td>AMD</td><td align="right">44794</td><td align="right">7.2%</td></tr> <tr><td>Google</td><td align="right">42921</td><td align="right">6.9%</td></tr> <tr><td>Red Hat</td><td align="right">38609</td><td align="right">6.2%</td></tr> <tr><td>Meta</td><td align="right">30757</td><td align="right">4.9%</td></tr> <tr><td>NVIDIA</td><td align="right">30555</td><td align="right">4.9%</td></tr> <tr><td>IBM</td><td align="right">20294</td><td align="right">3.2%</td></tr> <tr><td>Oracle</td><td align="right">18201</td><td align="right">2.9%</td></tr> <tr><td>Linaro</td><td align="right">17513</td><td align="right">2.8%</td></tr> <tr><td>(None)</td><td align="right">17146</td><td align="right">2.7%</td></tr> <tr><td>SUSE</td><td align="right">15243</td><td align="right">2.4%</td></tr> <tr><td>BayLibre</td><td align="right">14470</td><td align="right">2.3%</td></tr> <tr><td>Qualcomm</td><td align="right">11740</td><td align="right">1.9%</td></tr> <tr><td>NXP Semiconductors</td><td align="right">11214</td><td align="right">1.8%</td></tr> <tr><td>Microsoft</td><td align="right">10858</td><td align="right">1.7%</td></tr> <tr><td>Huawei Technologies</td><td align="right">10181</td><td align="right">1.6%</td></tr> <tr><td>Realtek</td><td align="right">9941</td><td align="right">1.6%</td></tr> <tr><td>YADRO</td><td align="right">9274</td><td align="right">1.5%</td></tr> <tr><td>Arm</td><td align="right">8545</td><td align="right">1.4%</td></tr> </table> </td></tr></table> </blockquote> <p> This list seldom contains surprises, and 6.12 follows in the usual pattern. One notable point is the appearance of Linutronix; that is a result of the merging of the final realtime patches and a fair amount of related refactoring work. <p> <h4>The longer cycle</h4> <p> While the kernel development cycle takes nine or ten weeks, almost without exception, it is a rare user who installs all of those releases. Instead, an increasing portion of the user body is running one of the long-term-support (LTS) releases and the stable updates that are built on top of them. By convention, the final release of the year becomes an LTS release. <p> As a result, there is an argument to be made that the real kernel development cycle takes about one year — the time that elapses between the LTS releases that are actually deployed by users. The 6.12 release, being the last release of 2024, is thus the end of that longer cycle, so there may be value in looking at the statistics for the full year. <p> Since the release of the last LTS kernel (6.6), the development community has created six releases, incorporating 86,715 non-merge changesets from 5,111 developers. The most active developers over the whole year were: <p> <blockquote> <table> <tr><th colspan=2 align="center">Most active 6.7-12 developers</th></tr> <tr><td width="50%" valign="top"> <table cellspacing=3 class="OddEven"> <tr><th colspan=3>By changesets</th></tr> <tr><td>Kent Overstreet </td><td align="right">3972</td><td align="right">4.6%</td></tr> <tr><td>Uwe Kleine-König </td><td align="right">1596</td><td align="right">1.8%</td></tr> <tr><td>Krzysztof Kozlowski </td><td align="right">1339</td><td align="right">1.5%</td></tr> <tr><td>Andy Shevchenko </td><td align="right">817</td><td align="right">0.9%</td></tr> <tr><td>Jani Nikula </td><td align="right">676</td><td align="right">0.8%</td></tr> <tr><td>Dmitry Baryshkov </td><td align="right">637</td><td align="right">0.7%</td></tr> <tr><td>Christoph Hellwig </td><td align="right">634</td><td align="right">0.7%</td></tr> <tr><td>Ville Syrjälä </td><td align="right">581</td><td align="right">0.7%</td></tr> <tr><td>Johannes Berg </td><td align="right">568</td><td align="right">0.7%</td></tr> <tr><td>Matthew Wilcox </td><td align="right">537</td><td align="right">0.6%</td></tr> <tr><td>Eric Dumazet </td><td align="right">489</td><td align="right">0.6%</td></tr> <tr><td>Ian Rogers </td><td align="right">474</td><td align="right">0.5%</td></tr> <tr><td>Geert Uytterhoeven </td><td align="right">471</td><td align="right">0.5%</td></tr> <tr><td>Darrick J. Wong </td><td align="right">446</td><td align="right">0.5%</td></tr> <tr><td>Thomas Zimmermann </td><td align="right">431</td><td align="right">0.5%</td></tr> <tr><td>Kees Cook </td><td align="right">401</td><td align="right">0.5%</td></tr> <tr><td>Arnd Bergmann </td><td align="right">395</td><td align="right">0.5%</td></tr> <tr><td>Sean Christopherson </td><td align="right">381</td><td align="right">0.4%</td></tr> <tr><td>Jeff Johnson </td><td align="right">378</td><td align="right">0.4%</td></tr> <tr><td>Jakub Kicinski </td><td align="right">374</td><td align="right">0.4%</td></tr> </table> </td><td width="50%" valign="top"> <table cellspacing=3 class="OddEven"> <tr><th colspan=3>By changed lines</th></tr> <tr><td>Kent Overstreet </td><td align="right">259293</td><td align="right">5.1%</td></tr> <tr><td>Aurabindo Pillai </td><td align="right">228673</td><td align="right">4.5%</td></tr> <tr><td>Hawking Zhang </td><td align="right">152950</td><td align="right">3.0%</td></tr> <tr><td>Ian Rogers </td><td align="right">133772</td><td align="right">2.6%</td></tr> <tr><td>Qingqing Zhuo </td><td align="right">101474</td><td align="right">2.0%</td></tr> <tr><td>Dmitry Baryshkov </td><td align="right">88968</td><td align="right">1.7%</td></tr> <tr><td>Hamza Mahfooz </td><td align="right">73053</td><td align="right">1.4%</td></tr> <tr><td>Arnd Bergmann </td><td align="right">71392</td><td align="right">1.4%</td></tr> <tr><td>Ard Biesheuvel </td><td align="right">70780</td><td align="right">1.4%</td></tr> <tr><td>Ben Li </td><td align="right">68066</td><td align="right">1.3%</td></tr> <tr><td>Lang Yu </td><td align="right">66939</td><td align="right">1.3%</td></tr> <tr><td>Philipp Hortmann </td><td align="right">63036</td><td align="right">1.2%</td></tr> <tr><td>Matthew Sakai </td><td align="right">58728</td><td align="right">1.2%</td></tr> <tr><td>Darrick J. Wong </td><td align="right">55467</td><td align="right">1.1%</td></tr> <tr><td>Matthew Brost </td><td align="right">51447</td><td align="right">1.0%</td></tr> <tr><td>Jakub Kicinski </td><td align="right">47447</td><td align="right">0.9%</td></tr> <tr><td>Matthew Wilcox </td><td align="right">40377</td><td align="right">0.8%</td></tr> <tr><td>Neil Armstrong </td><td align="right">36116</td><td align="right">0.7%</td></tr> <tr><td>Sarah Walker </td><td align="right">29771</td><td align="right">0.6%</td></tr> <tr><td>David Howells </td><td align="right">27675</td><td align="right">0.5%</td></tr> </table> </td></tr> </table> </blockquote> <p> Unsurprisingly, these results are consistent with what has been seen over the course of the last year. Overstreet, it should be noted, found his way to the top of both lists through the merger of a body of work that was developed out-of-tree for years. The main source of new lines of code coming into the kernel, though, was the seemingly endless stream of machine-generated header files for the amdgpu driver. <p> The top testers and reviewers over the longer cycle were: <p> <blockquote> <table> <tr><th colspan=2 align="center">Test and review credits in 6.7-12</th></tr> <tr><td width="50%" valign="top"> <table cellspacing=3 class="OddEven"> <tr><th colspan=3>Tested-by</th></tr> <tr><td>Daniel Wheeler </td><td align="right">1136</td><td align="right">14.1%</td></tr> <tr><td>Philipp Hortmann </td><td align="right">244</td><td align="right">3.0%</td></tr> <tr><td>Pucha Himasekhar Reddy </td><td align="right">214</td><td align="right">2.7%</td></tr> <tr><td>Arnaldo Carvalho de Melo </td><td align="right">124</td><td align="right">1.5%</td></tr> <tr><td>Michael Kelley </td><td align="right">101</td><td align="right">1.3%</td></tr> <tr><td>Neil Armstrong </td><td align="right">99</td><td align="right">1.2%</td></tr> <tr><td>Sohil Mehta </td><td align="right">92</td><td align="right">1.1%</td></tr> <tr><td>Rafal Romanowski </td><td align="right">85</td><td align="right">1.1%</td></tr> <tr><td>Nicolin Chen </td><td align="right">81</td><td align="right">1.0%</td></tr> <tr><td>Randy Dunlap </td><td align="right">64</td><td align="right">0.8%</td></tr> <tr><td>Björn Töpel </td><td align="right">57</td><td align="right">0.7%</td></tr> <tr><td>Babu Moger </td><td align="right">56</td><td align="right">0.7%</td></tr> <tr><td>Geert Uytterhoeven </td><td align="right">54</td><td align="right">0.7%</td></tr> <tr><td>Sujai Buvaneswaran </td><td align="right">54</td><td align="right">0.7%</td></tr> <tr><td>Guenter Roeck </td><td align="right">51</td><td align="right">0.6%</td></tr> <tr><td>Kees Cook </td><td align="right">50</td><td align="right">0.6%</td></tr> <tr><td>Helge Deller </td><td align="right">50</td><td align="right">0.6%</td></tr> <tr><td>Johan Hovold </td><td align="right">49</td><td align="right">0.6%</td></tr> <tr><td>Nathan Chancellor </td><td align="right">47</td><td align="right">0.6%</td></tr> <tr><td>Shameer Kolothum </td><td align="right">44</td><td align="right">0.5%</td></tr> </table> </td><td width="50%" valign="top"> <table cellspacing=3 class="OddEven"> <tr><th colspan=3>Reviewed-by</th></tr> <tr><td>Simon Horman </td><td align="right">1146</td><td align="right">2.1%</td></tr> <tr><td>Christoph Hellwig </td><td align="right">1009</td><td align="right">1.9%</td></tr> <tr><td>Krzysztof Kozlowski </td><td align="right">1002</td><td align="right">1.9%</td></tr> <tr><td>Konrad Dybcio </td><td align="right">826</td><td align="right">1.5%</td></tr> <tr><td>Dmitry Baryshkov </td><td align="right">697</td><td align="right">1.3%</td></tr> <tr><td>AngeloGioacchino Del Regno </td><td align="right">657</td><td align="right">1.2%</td></tr> <tr><td>David Sterba </td><td align="right">626</td><td align="right">1.2%</td></tr> <tr><td>Andy Shevchenko </td><td align="right">611</td><td align="right">1.1%</td></tr> <tr><td>Rodrigo Vivi </td><td align="right">574</td><td align="right">1.1%</td></tr> <tr><td>Ilpo Järvinen </td><td align="right">550</td><td align="right">1.0%</td></tr> <tr><td>Andrew Lunn </td><td align="right">536</td><td align="right">1.0%</td></tr> <tr><td>Rob Herring</td><td align="right">534</td><td align="right">1.0%</td></tr> <tr><td>Geert Uytterhoeven </td><td align="right">525</td><td align="right">1.0%</td></tr> <tr><td>Kees Cook </td><td align="right">465</td><td align="right">0.9%</td></tr> <tr><td>Matt Roper </td><td align="right">451</td><td align="right">0.8%</td></tr> <tr><td>Linus Walleij </td><td align="right">437</td><td align="right">0.8%</td></tr> <tr><td>Jani Nikula </td><td align="right">430</td><td align="right">0.8%</td></tr> <tr><td>Darrick J. Wong </td><td align="right">426</td><td align="right">0.8%</td></tr> <tr><td>Jeff Layton </td><td align="right">424</td><td align="right">0.8%</td></tr> <tr><td>Hawking Zhang </td><td align="right">418</td><td align="right">0.8%</td></tr> </table> </td></tr></table> </blockquote> <p> The most active employers (out of the 361 total) over the longer cycle were: <p> <p> <blockquote> <table> <tr><th colspan=2 align="center">Most active 6.7-12 employers</th></tr> <tr><td width="50%" valign="top"> <table cellspacing=3 class="OddEven"> <tr><th colspan=3>By changesets</th></tr> <tr><td>Intel</td><td align="right">11356</td><td align="right">13.1%</td></tr> <tr><td>(None)</td><td align="right">6881</td><td align="right">7.9%</td></tr> <tr><td>Google</td><td align="right">5920</td><td align="right">6.8%</td></tr> <tr><td>(Unknown)</td><td align="right">5668</td><td align="right">6.5%</td></tr> <tr><td>AMD</td><td align="right">5233</td><td align="right">6.0%</td></tr> <tr><td>Linaro</td><td align="right">5112</td><td align="right">5.9%</td></tr> <tr><td>Red Hat</td><td align="right">4863</td><td align="right">5.6%</td></tr> <tr><td>Huawei Technologies</td><td align="right">2459</td><td align="right">2.8%</td></tr> <tr><td>SUSE</td><td align="right">2319</td><td align="right">2.7%</td></tr> <tr><td>Meta</td><td align="right">2207</td><td align="right">2.5%</td></tr> <tr><td>Oracle</td><td align="right">1986</td><td align="right">2.3%</td></tr> <tr><td>Pengutronix</td><td align="right">1871</td><td align="right">2.2%</td></tr> <tr><td>Qualcomm</td><td align="right">1792</td><td align="right">2.1%</td></tr> <tr><td>NVIDIA</td><td align="right">1713</td><td align="right">2.0%</td></tr> <tr><td>IBM</td><td align="right">1612</td><td align="right">1.9%</td></tr> <tr><td>Renesas Electronics</td><td align="right">1574</td><td align="right">1.8%</td></tr> <tr><td>(Consultant)</td><td align="right">1227</td><td align="right">1.4%</td></tr> <tr><td>Arm</td><td align="right">1178</td><td align="right">1.4%</td></tr> <tr><td>NXP Semiconductors</td><td align="right">916</td><td align="right">1.1%</td></tr> <tr><td>Texas Instruments</td><td align="right">781</td><td align="right">0.9%</td></tr> </table> </td><td width="50%" valign="top"> <table cellspacing=3 class="OddEven"> <tr><th colspan=3>By lines changed</th></tr> <tr><td>AMD</td><td align="right">918483</td><td align="right">18.1%</td></tr> <tr><td>Intel</td><td align="right">540531</td><td align="right">10.6%</td></tr> <tr><td>Google</td><td align="right">378278</td><td align="right">7.4%</td></tr> <tr><td>(None)</td><td align="right">352401</td><td align="right">6.9%</td></tr> <tr><td>Linaro</td><td align="right">314793</td><td align="right">6.2%</td></tr> <tr><td>Red Hat</td><td align="right">308732</td><td align="right">6.1%</td></tr> <tr><td>(Unknown)</td><td align="right">292949</td><td align="right">5.8%</td></tr> <tr><td>Meta</td><td align="right">150897</td><td align="right">3.0%</td></tr> <tr><td>Oracle</td><td align="right">136086</td><td align="right">2.7%</td></tr> <tr><td>Qualcomm</td><td align="right">108629</td><td align="right">2.1%</td></tr> <tr><td>NVIDIA</td><td align="right">94799</td><td align="right">1.9%</td></tr> <tr><td>SUSE</td><td align="right">86590</td><td align="right">1.7%</td></tr> <tr><td>Realtek</td><td align="right">78260</td><td align="right">1.5%</td></tr> <tr><td>Emerson</td><td align="right">63036</td><td align="right">1.2%</td></tr> <tr><td>IBM</td><td align="right">61320</td><td align="right">1.2%</td></tr> <tr><td>Collabora</td><td align="right">58147</td><td align="right">1.1%</td></tr> <tr><td>Renesas Electronics</td><td align="right">56839</td><td align="right">1.1%</td></tr> <tr><td>Huawei Technologies</td><td align="right">50113</td><td align="right">1.0%</td></tr> <tr><td>NXP Semiconductors</td><td align="right">41451</td><td align="right">0.8%</td></tr> <tr><td>Microsoft</td><td align="right">38985</td><td align="right">0.8%</td></tr> </table> </td></tr></table> </blockquote> <p> Intel has cemented its position as the most prolific contributor of changesets over this year, with nearly double the number of the next company (Google) on the list. Otherwise, though, this list looks similar to <a href="/Articles/948970/">the 6.6 version</a> at the end of the last long cycle. <p> All told, the kernel's development process continues to incorporate changes and bring in new developers at a high rate (though that rate has been stable for the last few years). As of this writing, there are over 10,000 changes in linux-next waiting for the 6.13 merge window to open, so there is plenty of work to start the next development cycle (and the next year-long LTS cycle). As always, LWN will be there to tell you how it goes. <p><a href="/Articles/997959/#Comments">Comments (1 posted)</a> <p> <a name="997559"></a><h3 class="SummaryHL"><a href="/Articles/997559/">Fedora KDE gets a promotion</a></h3> <div class="FeatureByline"> By <b>Joe Brockmeier</b><br>November 15, 2024 </div> <p>The Fedora Project is set to welcome a second desktop edition to its lineup after months (or years, depending when one starts the clock) of discussions. The project recently decided to allow a new working group to move forward with a KDE Plasma Desktop edition that will sit alongside the existing GNOME-based Fedora Workstation edition. This puts KDE on a more equal footing within the project, which, it is hoped, will bring more contributors and users interested in KDE to adopt Fedora as their Linux distribution of choice.</p> <h4>A quick recap</h4> <p>In April, Fedora's KDE special interest group (SIG) put forward a <a href="https://lwn.net/ml/fedora-devel/CAJqbrbdmh5xZ0c8oM3VXqOdD7Nz_szWYH=4x5dBa+eDApDq11g@mail.gmail.com/">change proposal</a> to switch Fedora Workstation's desktop from GNOME to KDE. While there was little chance of that being adopted, it did lead to discussions that bore fruit in the form of a <a href="https://pagure.io/Fedora-Council/tickets/issue/504">request to upgrade</a> KDE to full edition status. On November 7 the Fedora Council <a href="https://pagure.io/Fedora-Council/tickets/issue/504#comment-943131">approved</a> that request, beginning with Fedora 42.</p> <p>In the early days of Fedora, users were left to their own devices to pick and choose software to install, including the window manager or desktop environment, if any. This was eventually deemed to be a disadvantage compared to other Linux distributions (namely Ubuntu) that provided a simpler, curated default set of packages which removed the "choose your own adventure" aspect of installing a Linux desktop.</p> <p>The Ubuntu philosophy tended to appeal to users coming from the Windows and Apple ecosystems, which presented no confusing choices about desktop environments—or, indeed, any need to install an operating system in the first place. While a "one desktop fits all" approach might sound stifling to experienced Linux users, new users often have no frame of reference for choosing between GNOME, KDE, Xfce, and others.</p> <!-- middle-ad --> <p>In 2013, the Fedora project assembled <a href="https://lwn.net/Articles/569795/">working groups</a> to <a href="https://lwn.net/Articles/569799/">develop plans and requirements</a> for three Fedora-based editions (originally called "products" or "flavors"): <a href="https://fedoraproject.org/cloud/">Fedora Cloud</a>, <a href="https://fedoraproject.org/server/">Fedora Server</a>, and <a href="https://fedoraproject.org/workstation/">Fedora Workstation</a>. The working group behind Fedora Workstation decided to standardize on GNOME as the desktop environment. The first iteration, Fedora Workstation 21, was <a href="https://lwn.net/Articles/625142/">released</a> in December 2014.</p> <p>If users wanted another desktop, they would need to install it separately or turn to <a href="https://spins.fedoraproject.org/">Fedora Spins</a> that featured their preferred desktop—if there was one. Spins were a concept that the Fedora project <a href="https://lwn.net/Articles/249251/">established in 2007</a> to target <a href="https://web.archive.org/web/20141216232319/http://spins.fedoraproject.org/about">specific use cases or subsets of users</a>. Spins are composed entirely of packages from Fedora's official package repositories, but do not enjoy the same level of support from the project. For example, spins receive little attention in announcements created by the Fedora Marketing team and are generally not release blocking. If, say, the Xfce desktop spin is horribly broken when it's time to ship Fedora 42, then the release train can leave the station without it.</p> <p>KDE, however, is an exception to this policy. The KDE spin was <a href="https://pagure.io/fesco/issue/1243#comment-31770">declared release blocking</a> ahead of the Fedora 21 release while the KDE SIG <a href="https://pagure.io/fesco/issue/1243#comment-31771">worked on a proposal</a> for Fedora to offer a KDE-focused product as well.</p> <h4>"Neither endorse nor oppose"</h4> <p>Now, a mere 10 years or so later, KDE is finally on its way to edition status—after the KDE SIG forced the discussion in April by proposing KDE replace GNOME in the Workstation edition. After much discussion Fedora Project Leader Matthew Miller <a href="https://discussion.fedoraproject.org/t/f42-change-proposal-fedora-plasma-workstation-system-wide/111343/41">suggested</a> that the KDE SIG negotiate with the Workstation working group about elevating KDE Plasma in some fashion. In May when LWN <a href="https://lwn.net/Articles/970929/">last covered the story</a>, the KDE SIG was <a href="https://pagure.io/fedora-workstation/issue/425#comment-908443">still waiting</a> on a response from the Fedora Workstation working group.</p> <p>On May 15, Michael Catanzaro <a href="https://pagure.io/fedora-workstation/issue/425#comment-910661">replied</a> that the Workstation working group had a response. The working group expressed concern that a second desktop edition could risk diluting Fedora's focus and jeopardize Fedora's growth:</p> <blockquote class="bq"> <p>We do not want users to be presented with a choice between multiple desktop environments. This would be extremely confusing for anybody who is not already an experienced Linux user. [...]</p> <p>The generic desktop use case is already satisfied by Fedora Workstation: it's a Linux desktop suitable for everybody except people who specifically want to use other desktop environments. Although a Fedora KDE edition would also fulfill this same role, we suggest not prominently advertising it as such to avoid introducing confusion as to which edition undecided users should download. Instead, it could be advertised as a desktop intended for people who want to use KDE Plasma specifically.</p> </blockquote> <p>At the same time, it acknowledged that KDE Plasma was a "<q>particularly high-quality desktop</q>", with an especially large community of users and developers. Failing to attract those users to Fedora, it said, "<q>will certainly limit Fedora's user base growth</q>". Therefore, it would "<q>neither endorse nor oppose the proposal for Fedora KDE Plasma Desktop to become a new Fedora edition</q>".</p> <h4>Personal systems working group</h4> <p>With the Workstation working group unwilling to work on a KDE edition, the KDE SIG set about <a href="https://pagure.io/fedora-kde/SIG/issue/510">creating its own working group</a>, the <a href="https://pagure.io/fedora-personalsystems/wg">Fedora Personal Systems Working Group</a> (Fedora PSWG). Following discussions at Fedora's <a href="https://fedoraproject.org/flock/">Flock</a> conference in August, the PSWG opened a <a href="https://pagure.io/Fedora-Council/tickets/issue/504">ticket</a> with the Fedora Council in September with a request to upgrade the KDE spin to edition status. If the move to full edition status were approved, the submission said, <em>then</em> Fedora's KDE SIG would withdraw the change request to replace GNOME with KDE Plasma for the Workstation edition.</p> <p>Participants in the <a href="https://discussion.fedoraproject.org/t/fedora-council-tickets-ticket-504-request-to-upgrade-fedora-kde-desktop-spin-to-edition-status-under-the-personal-systems-wg/131059">discussion thread</a> on Fedora's forum were largely supportive of elevating KDE to edition status. A few people were unhappy, however, with the "<q><a href="https://discussion.fedoraproject.org/t/fedora-council-tickets-ticket-504-request-to-upgrade-fedora-kde-desktop-spin-to-edition-status-under-the-personal-systems-wg/131059/3">kindergarten move</a></q>" of tying the withdrawal of the change proposal to replace GNOME with the acceptance of request to upgrade KDE to edition status. Miller <a href="https://discussion.fedoraproject.org/t/fedora-council-tickets-ticket-504-request-to-upgrade-fedora-kde-desktop-spin-to-edition-status-under-the-personal-systems-wg/131059/12">said</a> that the KDE SIG did that because it "<q>felt backed into that corner</q>" because the <a href="https://docs.fedoraproject.org/en-US/council/policy/edition-promotion-policy/">policy</a> for promoting a deliverable to edition status requires a distinct use case that "<q>a Fedora Edition is not currently serving</q>". By many interpretations, the GNOME-based Workstation edition already served the broad desktop use case, which means that no other desktop-focused editions need apply.</p> <p>That policy was <a href="https://pagure.io/Fedora-Council/tickets/issue/296">adopted</a> in 2020, when the project was in the process of adding two new editions, <a href="https://fedoraproject.org/iot/">Fedora IoT</a> and <a href="https://fedoraproject.org/coreos/">Fedora CoreOS</a>. Specifically, the policy's requirement that an edition address a "<q>distinct, relevant and broad use-case or user-base that a Fedora Edition is not currently serving</q>" seemed to conflict with having two desktop-oriented editions. However, Miller said that he was in favor of an exception to that policy because "<q>there is plenty of room to expand Fedora usage on the desktop generally</q>".</p> <p>On September 30, Miller <a href="https://discussion.fedoraproject.org/t/proposed-change-to-the-fedora-council-policy-for-edition-promotion/132206">started a discussion</a> about changing the edition promotion policy to explicitly allow the Fedora Council to make exceptions to the "distinct" rule "<q>when we determine that doing so best fits the Project's Mission and Vision</q>". In that discussion, he <a href="https://discussion.fedoraproject.org/t/proposed-change-to-the-fedora-council-policy-for-edition-promotion/132206/7">explained</a> that he wanted to keep the exception narrow, because there is a cost to the project for each edition:</p> <blockquote class="bq"> Quality, rel-eng, packagers, marketing, design, website, docs, Ask Fedora, and other teams are all asked to take on more. When a new Edition overlaps with an existing one (or changes to an Edition or in the world create an overlap between two existing Editions), that has a cost too. We want a family of Editions that support each other, not accidental zero-sum games. </blockquote> <p>The Fedora Council <a href="https://pagure.io/Fedora-Council/tickets/issue/507#comment-939766">approved</a> Miller's amendment to the editions policy on October 22. After that passed, discussion resumed on the request before the Fedora Council to upgrade KDE to full edition status. Miller <a href="https://pagure.io/Fedora-Council/tickets/issue/504#comment-940085">noted</a> that the request would need "full consensus", which the council guidelines define as at least three votes in favor and no votes against to pass. On November 7, the request was <a href="https://pagure.io/Fedora-Council/tickets/issue/504#comment-943131">marked approved</a> with nine votes in favor and no votes abstaining or against the proposal.</p> <h4>Next steps</h4> <p>Though the vote passed, a few topics came up that were set aside for later discussion. For example, a need to <a href="https://pagure.io/Fedora-Council/tickets/issue/504#comment-940379">define the scope of testing</a>, and a need to <a href="https://pagure.io/Fedora-Council/tickets/issue/504#comment-941917">develop the marketing story</a> for Fedora having two desktop editions. Miller also said he was <a href="https://pagure.io/Fedora-Council/tickets/issue/504#comment-940089">against</a> the concept of a personal systems workgroup "<q>which does not include at minimum all Desktop Editions</q>". Neal Gompa, however, pushed back on the idea of forcing the GNOME and KDE editions into a single workgroup:</p> <blockquote class="bq"> <p>It doesn't actually make sense to force everyone into the same group. The Personal Systems WG already has plans for expansion and at least two SIGs will be part of it at launch. There are growth prospects for multi-stakeholder relevance, but forcing it is not part of the plan.</p> <p>Not to mention, we already don't do this for any of the server-side teams: CoreOS, Cloud, and Server are not forced under a single banner either. It is unreasonable to require that for us.</p> </blockquote> <p>Miller <a href="https://pagure.io/Fedora-Council/tickets/issue/504#comment-940947">suggested</a> the working group might take on a more specific name if all desktop editions could not live under one working group, such as the KDE Edition WG, but Gompa <a href="https://pagure.io/Fedora-Council/tickets/issue/504#comment-940949">objected</a> to that as well. For now, there's no decision either way.</p> <p>The experience for Fedora KDE Plasma users is unlikely to change much as a result of its upgrade to edition, but the bureaucratic load for the KDE SIG/PSWG will increase substantially. The edition policy spells out work that will need to be done before the Fedora KDE Plasma Desktop spin can be an edition. If the name changes, which seems likely, it will need trademark approval from the Fedora Council. It will need to have a full product requirements document (PRD) similar to the <a href="https://fedoraproject.org/wiki/Workstation/Workstation_PRD">PRD for Workstation</a> to define its target market, the user types it would try to appeal to, the core applications, unique policies, and more. And, of course, there are marketing materials and more that will need to be revised or created. That is no small undertaking.</p> <p>Currently, the plan appears to be to introduce the yet-to-be-named KDE edition with Fedora 42, which is due to be released in May 2025. This means that the work to upgrade KDE Plasma to full edition status would need to be completed, or close to complete, by the Fedora—42 beta launch in March.</p> <p>It has been a long journey for Fedora KDE to reach edition status, and it will be interesting to see whether its elevation results in significantly more users for KDE and Fedora in the coming years.</p> <p><a href="/Articles/997559/#Comments">Comments (8 posted)</a> <p> <a name="998153"></a><h3 class="SummaryHL"><a href="/Articles/998153/">Book review: Run Your Own Mail Server</a></h3> <div class="FeatureByline"> By <b>Joe Brockmeier</b><br>November 19, 2024 </div> <p>The most common piece of advice given to users who ask about running their own mail server is <em><a href="https://lwn.net/Articles/987566/">don't</a></em>. Setting up and securing a mail server in 2024 is not for the faint of heart, nor for anyone without copious spare time. Spammers want to flood inboxes with ads for questionable supplements, attackers want to abuse servers to send spam (or worse), and getting the big providers to accept mail from small servers is a constant uphill battle. Michael W. Lucas, however, encourages users to thumb their nose at the "<q>Email Empire</q>", and declare email independence. His self-published book, <em><a href="https://mwl.io/nonfiction/tools#ryoms">Run Your Own Mail Server</a></em>, provides a manual (and manifesto) for users who are interested in the challenge.</p> <img src="https://static.lwn.net/images/2024/ryoms-cover.png" border=0 hspace=5 vspace=5 align="right" alt="[Cover: Run Your Own Mail Server]" title="Cover: Run Your Own Mail Server" width=250 height=375> <p><em>Run Your Own Mail Server</em> came to my attention toward the end of its successful <a href="https://www.kickstarter.com/projects/mwlucas/run-your-own-mail-server">Kickstarter campaign</a>. About 20 years ago I decided that hosting my own email was a hobby I no longer wished to pursue. I changed my MX records to an external provider and powered off the long-suffering Pentium Pro server for the last time. Regrets were few.</p> <p>However, the general message of the campaign ("<q>By running your own email, you seize control of your communications.</q>") appealed to me. Paying for email hosting has freed up some time, and it's certainly cheaper for one or two users if one believes that their time is worth money, but at the cost of giving up control. I was interested in dipping my toes back in the email waters to see if it was time to resume managing my own mail.</p> <p>Lucas provided PDF and EPUB versions of the book for this review, and I worked from the PDF. The book is 350 pages and is currently available for about $15 for the digital editions, and about $35 for a paperback edition. Electronic editions are the cheaper and faster way to get one's hands on the title, but I would recommend picking up a print version for anyone serious about running their own mail server. This is the kind of tech book that one would like to annotate, plaster a few sticky notes and page markers in, and so forth. An early draft of the introduction is <a href="https://mwl.io/archives/22653">available on his site</a>.</p> <h4>Who, why, and what</h4> <p>The introductory chapter establishes who should read the book, why they should be interested in running a mail server, and what platforms and tools Lucas will cover. The book is aimed solidly at system administrators, or at least those with substantial administration skills.</p> <p>Lucas makes clear from the outset that readers are expected to be able to manage their own operating system, and extrapolate from examples rather than follow them blindly. For instance, he notes that he takes his examples from FreeBSD or Debian Linux—so the path to configuration files may differ for readers who are setting up these services on other systems.</p> <!-- middle-ad --> <p>Readers are expected to already have an understanding of things like DNS, networking, managing certificates with Let's Encrypt, and more. Or, at least, readers must be willing to become familiar—Lucas provides some recommendations for his own books on system administration as well as Cricket Liu and Paul Albitz's <a href="https://www.oreilly.com/library/view/dns-and-bind/0596100574/"><em>DNS and Bind</em></a>. If dabbling with DNS records, logging, TLS certificates, databases (yes, plural), user management, and more sounds fun, then this is exactly the book to pick up.</p> <p>The introduction provides a brief look at the history of email, covers things like Simple Mail Transport Protocol (SMTP), MX records, Sender Policy Framework (SPF), and his choices of software. The book covers using <a href="https://www.postfix.org/">Postfix</a> as the mail transfer agent (MTA), <a href="https://www.dovecot.org/">Dovecot</a> as the Internet Message Access Protocol (IMAP) server, <a href="https://roundcube.net/">Roundcube</a> for webmail, and <a href="http://www.mutt.org/">Mutt</a> as the mail user agent (MUA), or mail client. Often a book's introduction can be safely skipped over, but it's not recommended here, as it contains information and context that will be needed later.</p> <h4>Digging in</h4> <p>The next two chapters look at SMTP, Postfix, and Dovecot in more detail and start the reader on the journey to actually setting up a mail server to send and receive email. Two servers, actually: readers need to have two hosts connected to the internet to properly follow along with the book. This enables readers to test sending and receiving mail before trying to send mail to the world at large (and risk having a misconfigured server wrongly identified as a spam host).</p> <p>It's easy to find guides online to <a href="https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-postfix-on-ubuntu-20-04">configure Postfix</a> or <a href="https://ubuntu.com/server/docs/install-and-configure-dovecot">Dovecot</a> with a set of explicit instructions one can buzz through in a few minutes. That is not the approach that Lucas takes. Instead, he walks through setting up Postfix and Dovecot while taking the time to explain the various configuration options and commands in a sort of lecture format. This method is generally enjoyable if one wants to know why, as well as how, to do things, but it's not always the most efficient way to convey setup instructions. Then again, if one is seeking efficiency, the most expedient thing to do is pay a provider to manage email and let it be somebody else's problem.</p> <h4>Scaling up</h4> <p>By the end of chapter 3, readers should have a pair of mail servers that can send, receive, and deliver messages to local users in the <a href="https://en.wikipedia.org/wiki/Maildir">Maildir</a> format. That is a useful foundation, but hardly what most would consider a functional mail setup—the mail servers are not ready, for example, to work with external clients—so users can only send mail while logged into the servers. Next Lucas turns to addressing virtual domains, IMAP, setting up authentication for users to send mail, and installing the web-based PostfixAdmin tool.</p> <p>Chapter 3, "Postfix and Dovecot Setup", might have worked better as two chapters that focused on the respective programs. The coverage of Postfix seemed more thorough and organized than Dovecot's. For example, Lucas starts describing Dovecot's local delivery agent, (<tt>dovecot-lda</tt>) setup in Chapter 3 and then picks it up again in Chapter 4. The instructions, at least on my Debian 12 system, are somewhat incomplete and required further troubleshooting because the service did not have permissions to open the appropriate log files.</p> <p>No book on running mail servers would be complete without addressing the topic of spam, and much of <em>Run Your Own Mail Server</em> is devoted to the topic in one way or another. Lucas devotes two chapters to his choice of spam filtering tool, <a href="https://rspamd.com/">Rspamd</a>, which LWN <a href="https://lwn.net/Articles/732570/">covered</a> in 2017. Given the complexity of Rspamd, compared to setting up Apache SpamAssassin, this seemed like a bit of overkill at first—but it seems to be an integral part of the way that Lucas likes to manage mail.</p> <p>Chapter 7, "Rspamd Essentials", starts down the path of setting up Rspamd and requisite components. It spends a fair amount of time on the <a href="https://rspamd.com/doc/configuration/ucl.html">Universal Configuration Language</a> (UCL) used by Rspamd as well as setting up separate Redis instances for Rspamd's configuration and Bayesian data, respectively. (He does note the <a href="https://lwn.net/Articles/966631/">Redis license change</a> and acknowledges that users may need to migrate to another database down the road.)</p> <p>The book picks up again with Rspamd in Chapter 14, "Managing Rspamd", after covering <a href="https://en.wikipedia.org/wiki/Sender_Policy_Framework">SPF</a> records, <a href="https://dkim.org/">DomainKeys Identified Mail</a> (DKIM), <a href="https://dmarc.org/">DMARC</a>, block lists, setting up web mail with Roundcube, and filtering mail using <a href="https://en.wikipedia.org/wiki/Sieve_%28mail_filtering_language%29">Sieve</a>. The last time I managed my own mail, SPF was in its infancy and things like DMARC didn't exist yet. I found these chapters to be a helpful overview of those topics as well as useful in setting up SPF and DMARC records. The reason Rspamd setup is covered early on, and then set aside for several chapters, is that Lucas also recommends it for use in DKIM signing and verification rather than <a href="http://www.opendkim.org/">OpenDKIM</a>. He does double back and cover OpenDKIM setup late in the book for instances where readers might want to set up mail servers to send, but not receive mail, saying that Rspamd is overkill for hosts that won't receive mail.</p> <p>Chapter 9 covers protocol checks and block lists to reduce spam that makes it to users' inboxes. It briefly touches on the <a href="https://en.wikipedia.org/wiki/Robustness_principle">robustness principle</a>, also known as Postel's Law after <a href="https://en.wikipedia.org/wiki/Jon_Postel">Jon Postel</a>. Lucas suggests that the principle, "<q>be conservative in what you do, be liberal in what you accept from others</q>", favors spammers. He explains setting up <a href="https://www.postfix.org/postscreen.8.html"><tt>postscreen</tt></a> to look for telltale signs that incoming connections are from spambots. This includes comparing against against <a href="https://en.wikipedia.org/wiki/Domain_Name_System_blocklist">Domain Name System blocklists</a> (DNSBLs) as well as <a href="https://www.dnswl.org/">DNSWL</a> to identify trustworthy mail servers. The chapter also discusses more "intrusive" checks such as looking for non-SMTP commands or improper line feeds. The SMTP protocol specifies carriage-return with line feed (CRLF), so if a client sends bare line feeds (LFs) instead, there's a good chance it's a poorly programmed spambot. Of course, not everything that's outdated or poorly programmed is a spambot—so Lucas also discusses how to wave through connections from legitimate organizations that have badly behaved network devices or ancient mail servers.</p> <p>Overall, I enjoyed and would recommend <em>Run Your Own Mail Server</em> for those comfortable with managing their own services, and who are willing to put in the work. It should be clear after reading the title that running a mail server is a hobby much like gardening: the work is never "done", it requires constant tending and eternal vigilance against pests. Currently, I'm on the fence about doing the long-term work to migrate back to self-hosting—but much more apt to do so after reading the book.</p> <p>Readers who are looking for a book that provides a step-by-step set of instructions to be typed out will probably not be satisfied. The book is not well-suited for skimming over in a rush to set up a mail server. Lucas actually seeks to help readers understand what they are doing rather than running through a few steps by rote and hoping commands, syntax, and protocols never change.</p> <p>The book is also meant to empower readers to be good communal email citizens and run an email server for a small organization, group, or just themselves. It does not cover every topic, or ready a reader to set up email for thousands of users. He touches on a few issues of scale, such as how to send email to many recipients at once (like a newsletter) while avoiding being consigned to spam purgatory by providers like Google, Microsoft, and Yahoo. But routinely handing massive email traffic, splitting out services among multiple servers, or dealing with hundreds or thousands of users is beyond the scope of the book.</p> <p>Some books are like GPS navigation: set a destination and get what the author believes to be the shortest and fastest route with turn-by-turn instructions. Lucas occasionally takes the reader on the scenic route, sometimes navigating by landmarks instead of highway signs, and occasionally stopping at tourist attractions. One way gets there fast, but the other way builds skill and confidence in navigating solo.</p> <p><a href="/Articles/998153/#Comments">Comments (59 posted)</a> <p> </div> <p> <b>Page editor</b>: Jonathan Corbet<br> <h2>Inside this week's LWN.net Weekly Edition</h2> <ul> <li> <a href="/Articles/998146/">Briefs</a>: Bhyve and Capsicum audit; PyPI digital attestation; AlmaLinux 9.5; Rocky Linux 9.5; Blender 4.3; CHICKEN 6; FreeCAD 1.0; Incus 6.7; Quotes; ... <li> <a href="/Articles/998147/">Announcements</a>: Newsletters; conferences; security updates; kernel patches; ... </ul> <b>Next page</b>: <a href="/Articles/998146/">Brief items>></a><br> </div> <!-- ArticleText --> </div> <!-- middlecolumn --> <div class="rightcol not-print"> <div id="azk93271_right_zone"></div> </div> </div> <!-- maincolumn --> <br clear="all"> <center> <P> <span class="ReallySmall"> Copyright © 2024, Eklektix, Inc.<BR> Comments and public postings are copyrighted by their creators.<br> Linux is a registered trademark of Linus Torvalds<br> </span> </center> </body></html>