Re: [PATCH 0/3] vmsplice: make vmsplice a trivial wrapper for preadv2/pwritev2
Linus Torvalds <[email protected]>
| Newsgroups | org.kernel.vger.linux-api,dev.linux.lists.patches,org.kernel.vger.linux-fsdevel,org.kernel.vger.linux-kernel,org.kernel.vger.netdev,org.kvack.linux-mm |
|---|---|
| Message-ID | <CAHk-=whkGbMoP-Dym8pAd3hV21=BZST+6sK++1X038+9Q-TgeA@mail.gmail.com> |
On Wed, 3 Jun 2026 at 11:28, Linus Torvalds <[email protected]> wrote: > > But even then you need to have a *handle* to the buffers for the > general case, and that's what the pipe fd ends up then still > effectively being. Again: for sendfile, you don't need the handle, because you can just "read the file data again". But the the handle is needed for any buffering that can't do that - iow pretty much *any* other case than a file-backed source. So the original use-cases included things like copying media data from a TV capture card to a GPU for outputting in a window. There it's actually the intermediate buffer that is the important thing, and it needs to have a lifetime that is independent of the system call itself, because the system call may be interrupted by signals etc, and you can't just "read the data again" when you restart. So the whole idea with splice() is that you have an input, an output, and a stateful buffer between the two that has a lifetime. Having just a iov_iter isn't enough - even with the current much more capable iov_iter we have now (compared to when splice came to be: two decades ago when the modern iov_iter didn't even exist). You have to have that notion of a buffer with a lifetime. (iov_iter came a couple of years later, but it then took many many years for it to become the powerful thing it is today where you can put almost arbitrary data into it - it started as purely a user space iovec iterator, all the bvec/kvec etc stuff that you need for IO buffering came a decade later) So there's historical reasons for the use of pipes, but there really is a very fundamental reason for it too: wanting to *generic* data transfer between two points, not sendfile. It's worth noticing that in the generic case, zero-copy isn't really even an issue. When you think operations like "splice TV capture input to a pipe", you typically need to allocate the pages that you then DMA into *anyway*, and you'd just put those pages into the pipe. And the facty that you can then just take the data directly from those pages when you splice from the pipe to whatever GPU engine that does the decoding is kind of secondary. So again: the big deal with splice() and the pipe isn't really about zero-copy. It's the in-kernel buffers where the drivers control the allocation and you don't have some "user space allocates memory, then kernel looks that allocation up and uses it" model. Having less copies is kind of incidental. It *might* happen just because it's natural when some streaming device just gives it data away and doesn't care after the fact. The problem with splicing from a file has been exactly the fact that it's *not* streaming data, and the filesystem zero-copy case gave direct access to the long-term cache. Which is undoubtedly good for performance. But it fundamentally *requires* that the sink is trustworthy. Which has been problematic. That's why sendfile() is bad. Not because splice itself is a bad concept, but because you have to have that absolute trust across components. Linus