|
|
Log in / Subscribe / Register

Kernel development

Brief items

Kernel release status

The current development kernel is 4.3-rc4, released on October 4. Linus said: "You all know the drill by now. It's Sunday, and there is a new release candidate out there."

Stable updates: 3.14.54 and 3.10.90 were released on October 1; 4.2.3 and 4.1.10 followed on October 3.

Comments (none posted)

Quote of the week

Outside of servers it's no longer worth the effort of upstreaming. We're seeing the evolution of a different model of contribution both inside and outside of the kernel, where you have a lot of forking of trees, people taking code from each others forks and when needed getting together to create trees for their shared ends (eg Linaro), or where everyone by habit goes direct to the "pre-merge" trees - eg for graphics. Everyone does it, they talk about doing it "for now", "temporarily" or they don't talk about it because it's against the myth of the one upstream but they all do it because it's economic necessity.

Development cycles are getting faster, and the kernel is now relatively so slow to evolve that a phone or IoT product can be developed, released, discontinued and obsoleted before the driver is accepted upstream - by which time it's just a liability (although the style police will patch it for ten years without anyone ever using or testing it)

Alan Cox

Comments (12 posted)

Sharp: Closing a door

Sarah Sharp has made official her departure from the kernel development community. "I didn’t take the decision to step down lightly. I felt guilty, for a long time, for stepping down. However, I finally realized that I could no longer contribute to a community where I was technically respected, but I could not ask for personal respect. I could not work with people who helpfully encouraged newcomers to send patches, and then argued that maintainers should be allowed to spew whatever vile words they needed to in order to maintain radical emotional honesty. I did not want to work professionally with people who were allowed to get away with subtle sexist or homophobic jokes. I feel powerless in a community that had a 'Code of Conflict' without a specific list of behaviors to avoid and a community with no teeth to enforce it."

Comments (361 posted)

Kernel development news

Dropping the timer tick — for real this time

By Jonathan Corbet
October 7, 2015
The kernel reached a landmark of sorts in 2013 when nearly full tickless support was merged for the 3.10 release. This work allows the timer interrupt to be disabled when a single process is running on a CPU; that gives the process uninterrupted access to the CPU for as long as it avoids calling into the kernel. It turns out, though, that some applications have such stringent requirements that even "nearly full" support is not good enough. For those, Chris Metcalf's task isolated mode may fill the bill — but first, it must get past the review process.

Tickless mode is generally needed by applications that cannot afford to ever lose access to the CPU. A common example is high-bandwidth networking applications that do all of their packet processing (and protocol work) in user space. If this type of application is interrupted, it can drop packets into an unsightly mess on the floor. Tickless mode seeks to prevent such troubles by directing all interrupts and kernel housekeeping work to other CPUs so that the application never stops running as long as it doesn't, itself, call into the kernel.

The current tickless mode is not a 100% solution, though, in that it still allows the timer interrupt to fire once every second. Any other timers that may have been set (perhaps in response to something the application did) will also be allowed to fire. For some applications, a reduction in interrupts by two or three orders of magnitude is still not enough; they truly want it all, even if the cost is high.

Chris's patch is meant to let these applications have it all. An application running on a CPU that has been configured for tickless operation (done with the nohz_full= boot option) can invoke a new prctl() command (PR_SET_TASK_ISOLATION) to enter the fully isolated mode. Processes that want to ensure that they will stay in this mode can turn on the strict enforcement option by adding the PR_TASK_ISOLATION_STRICT bit in the prctl() call; should a process do anything that causes an entry into the kernel while strict mode is on, it will be summarily killed.

The isolation mode is much like the ordinary tickless mode, with one exception: the kernel carries out a number of actions whenever that process returns to user space to ensure that it will not be interrupted. That return can happen at the end of the prctl() enabling isolation mode, or, if the strict option has not been set, after any arbitrary system call while isolation mode is enabled.

Some of the return-to-user-mode work is fairly straightforward. The memory-management subsystem does some statistics collection through the "vmstat" mechanism, which is run from a delayed workqueue entry; in full isolation mode, this work is turned off. A call to lru_add_drain() is made to ensure that the CPU will not be asked to free up CPU-local pages while it is running in user space. And, most controversially, the CPU will busy-wait until there are no more pending timers to run.

The problem with the busy wait, of course, is that there is no way of knowing just how long it will take for the pending timers to expire. If some bit of code has set a timer for sometime next year, the loop will spin for that long. The code is safe (if inelegant) if one "knows" that, for a given workload, no overly inconvenient timers will be set. But in the wider world that the kernel runs in, assuming that timer users will never get in the way is asking for trouble. For this reason, reviewers like Thomas Gleixner are insisting that the timer problem be solved properly, by ensuring that unwanted timers will not be set in the first place.

Interestingly, both Chris and Thomas seem to agree that it would be best to just not have timers running while isolation mode is active. The difference seems to be that Chris worries that it will never be possible to identify every situation where a timer might be set or to prevent the introduction of new timers in the future. As he put it:

In general, the hard task-isolation requirement is something that is of particular interest only to a subset of the kernel community. As the kernel grows, adds features, re-implements functionality, etc., it seems entirely likely that odd bits of deferred functionality might be added in the same way that RCU, workqueues, etc., have done in the past. Or, applications might exercise unusual corners of the kernel's semantics and come across an existing mechanism that ends up enabling kernel ticks (maybe only one or two) before returning to userspace. The proposed busy-loop just prevents that from damaging the application.

This mode, he added, is only active for applications that have explicitly requested it, and only when they are the only process running on a core that has been configured for tickless operation. In such situations, the busy wait for timer events should not cause any harm.

Thomas, though, is convinced that the current approach is dancing around a couple of problems that have to be solved in the general case. There are reasons for the continued existence of the once-per-second tick; they include CPU-usage accounting and more. Just disabling that tick without getting a handle on those problems may work for Chris's use case, but it's likely to run into trouble with others. Until these problems are solved, getting this work into the kernel is likely to be difficult.

Chris seems prepared to try to solve these problems. He has proposed reworking the patch set to eliminate the busy-wait loop; instead, it would simply reschedule if any other processes are ready to run. The presence of other runnable processes is the main reason for an inability to disable the timer tick; it rules out running in the isolated mode in any case. Then, he plans to add a debugging-oriented mode that disables the once-per-second tick in "tickless" mode, making it possible to research the problems caused by doing without a timer tick entirely. With that infrastructure in place, he (along with any other interested developers) will be able to track down the sources of unwanted timer ticks and make them go away.

The road to a true solution to the timer-tick problem could be a long one; it is not easy to remove an assumption that has been fundamental to the kernel's design from the beginning. Once the work is done, though, the result should be more than just a fully isolated mode for a small niche use case; it should result in better performance for more ordinary systems as well. The timer tick is, to a great extent, a holdover from the days before Linux existed; there may soon come a time when we don't need it much anymore.

Comments (4 posted)

copy_file_range()

By Jonathan Corbet
October 7, 2015
Computers tend to spend a lot of time copying files. Often, the underlying filesystems have ways to accelerate that task, but, as a general rule, copying is still done with a user-space loop reading chunks of data from one file and writing to another. Over the years, there have been efforts to provide access to faster file-copy mechanisms (see the reflink() discussion, for example), but no solution has found its way into the mainline. Hope springs eternal, though, so there is a new initiative that might just make it over the bar.

This initiative is the copy_file_range() patch set posted by Anna Schumaker. It is built on some earlier work by Zach Brown, with a number of enhancements added on top. This patch set adds a new system call:

    ssize_t copy_file_range(int fd_in, loff_t *off_in, int fd_out,
    			    loff_t *off_out, size_t len, unsigned int flags);

In its basic form, this system call will copy len bytes starting at offset *off_in in the file represented by fd_in to the offset *off_out in fd_out. If either of the offsets is NULL, the operation will start at the current file position (the ability to distinguish NULL from zero is the reason why pointers are used for the offsets). The return value is the number of bytes copied, which, as usual, may be less than what was requested.

In the initial version of copy_file_range(), the two files were required to be on the same mount point (but they could not be the same file), and flags had to be zero. Anna's work has removed those limitations and added three mutually exclusive flags:

  • COPY_FR_COPY means to copy the data normally, accelerating the work at the filesystem level if possible.

  • COPY_FR_REFLINK asks for the destination file to refer to the existing copy of the data without actually copying it. Some filesystems (Btrfs, for example) are able to share references to file blocks in this way.

  • COPY_FR_DEDUP is like COPY_FR_REFLINK, but it only succeeds if the destination range already contains the same data as the source. The end result is files that look the same as before, but which are now sharing the data on-disk. It is thus a way of removing blocks of duplicated data within the filesystem.

The COPY_FR_COPY operation will, in the absence of filesystem-level acceleration, copy the data directly through the kernel page cache; it is essentially a splice() operation. Copying through the page cache in this way is clearly more efficient than doing the copy in user space, since it avoids the need to copy the data out of the kernel and back in again. If possible, of course, copying with COPY_FR_REFLINK will be the most efficient approach.

At the system-call level, only one of these flags may be set. But, within the kernel, the code looks like this:

    /* Default behavior is to try both. */
    if (flags == 0)
	flags = COPY_FR_COPY | COPY_FR_REFLINK;

So most users are likely to just want to provide zero as the flags value; that will result in a "reflink" copy if possible, and an ordinary copy otherwise.

At the filesystem level, the patch adds a new method to the ever-growing file_operations structure:

    ssize_t (*copy_file_range)(struct file *in, loff_t off_in,
    			       struct file *out, loff_t off_out,
			       size_t len, unsigned int flags);

The interface is similar to the system call except that file structures are used and the offsets are passed directly (reading the offsets from user space is handled at the system-call level). The flags value describes how the copy should be performed; as noted above, it might have more than one option set. This function, if provided, should attempt to perform the copy using the method(s) requested. If the function is absent or returns failure, the kernel will, if the COPY_FR_COPY flag is set, fall back to copying through the page cache.

This patch set has been through a number of review cycles at this point, and the flow of comments has slowed considerably. There do not seem to be any concerns that would keep this work out of the 4.4 kernel at this point — though surprises are always possible in kernel development. Barring any such, the long discussion on accelerated copy operations may be just about at an end.

Comments (16 posted)

strscpy() and the hazards of improved interfaces

By Jonathan Corbet
October 7, 2015
Back in the distant past (May 2015), LWN looked at a couple of efforts to provide improved string-handling primitives to the kernel. One of those two was recently merged, while the other has run into trouble; both cases highlight a fundamental concern Linus has about this type of kernel patch. The end result is that it is possible to evolve the kernel toward safer interfaces, but attempts to do so as a series of mass changes will probably not end well.

Normally, one does not expect to see a new API merged into the mainline for an -rc4 release, but Linus decided to make an exception when he pulled in the strscpy() patch just before 4.3-rc4. That patch set has changed a bit since it was examined here, though the intent is the same: to provide a string-copy API that is safer and easier to use than strncpy() or strlcpy(). The new copy function is:

    ssize_t strscpy(char *dest, const char *src, size_t count);

This function will copy the string found in src to dest, taking care not to overflow dest, which is count bytes long. Unlike strncpy(), it always null-terminates the destination string. The return value is the number of characters copied (without the trailing NUL byte) — unless the string would not fit into dest, in which case the return value is -E2BIG.

Unlike previous versions, strscpy() will always copy what it can, returning a truncated string in dest if the whole thing does not fit. That change took away the need for the strscpy_truncate() variant, so that function is no longer provided. Opinions may differ on whether returning a truncated string is the right thing to do, but there were enough opinions in favor of doing so that this change needed to be made to get the patch merged.

There are a number of advantages claimed for this API. It lacks an internal race condition found in the others, making it more robust in the face of a string that changes while it is being copied. The return value, it is claimed, more clearly indicates overflow than the value returned by strlcpy(). Unlike strncpy(), the result is always a null-terminated string. In the end, we might have finally come up with a reasonable string-copy function after about four attempts — not bad for such a complex task.

Anybody who is firing up their editor to start converting call sites in the kernel to strscpy() may want to reconsider, though. There is a warning in both the fate of parse_integer() and Linus's comments around the merging of strscpy().

parse_integer() is the other string function covered in the May article; its purpose is to make string-to-integer conversions easier and more robust. Linus recently got rather upset about this patch set which, he thought, changed the semantics of the API and introduced bugs. Various call sites were changed to the new functions and, in the process, some of them were broken. The idea was that parse_integer() would be a replacement for the kernel's existing integer-conversion functions (simple_strtoul(), kstrtoul(), and the like) but that the actual act of replacing those functions introduced regressions.

Linus was clearly afraid that the strscpy() patch could end up being a source of regressions as well. That wouldn't happen with the patch set itself, which does not convert any existing strncpy() or strlcpy() call sites. The problem happens when other, well-intentioned developers start doing those conversions. Linus described his worries in the merge commit that brought in strscpy():

So why did I waffle about this for so long?

Every time we introduce a new-and-improved interface, people start doing these interminable series of trivial conversion patches.

And every time that happens, somebody does some silly mistake, and the conversion patch to the improved interface actually makes things worse. Because the patch is mindnumbing and trivial, nobody has the attention span to look at it carefully, and it's usually done over large swatches of source code which means that not every conversion gets tested.

To try to head off such an outcome, Linus has made it clear that he will not be accepting patches that do mass conversions to strscpy() (note though that certain developers are already considering mass conversions anyway). It is there to be used with new code, but existing code should not be converted without some compelling reason to do so — or without a high level of attention to the possible implications of the change.

One might be tempted to think that this proclamation from Linus signals the end of the "trivial clean-up patch" era. But that would almost certainly be reading too much into what he said. Patches that do not make functional changes to the code do not, one would hope, pose the same sort of risk that API replacements do. So the flow of white-space adjustments is likely to continue unabated. But developers who want to convert a bunch of working code to a "safer" interface may want to think twice before sending in a patch.

Comments (55 posted)

Patches and updates

Kernel trees

Linus Torvalds Linux 4.3-rc4 ?
Greg KH Linux 4.2.3 ?
Greg KH Linux 4.1.10 ?
Luis Henriques Linux 3.16.7-ckt18 ?
Greg KH Linux 3.14.54 ?
Steven Rostedt 3.14.53-rt54 ?
Steven Rostedt 3.12.48-rt66 ?
Greg KH Linux 3.10.90 ?
Steven Rostedt 3.10.89-rt97 ?

Architecture-specific

Core kernel code

Development tools

John Kacur rt-tests-v0.95 ?

Device drivers

Device driver infrastructure

Filesystems and block I/O

Memory management

Kirill A. Shutemov THP refcounting redesign ?

Networking

Gavin Shan NCSI Support ?

Security-related

Miscellaneous

Page editor: Jonathan Corbet
Next page: Distributions>>


Copyright © 2015, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds