Hi Laurent, I had a closer look at extending IOV_REMOVE_HEADER() and the rest to handle discontinuous buffers, but I realised it's a bit more complex than I thought. What we need to do is a bit different depending on whether we're sending or receiving. The single current user of IOV_REMOVE_HEADER() is sending (guest Rx), as are the places I had been thinking about using it. For the send path, obviously, it's not helpful to linearise the section from the IOV, instead we need to write things into the IOV, maybe discontiguously. The IOV_REMOVE_HEADER() interface doesn't really work for this. I was wondering about a sort of "reserve/set" interface. You "reserve" the header region, which gives you either a pointer directly into the iov, or a pointer to a temporary buffer. Then you "set", which is a no-op if you had a direct pointer, but if you had the temp buffer, then it copies back with iov_from_buf(). I don't love this interface; it's pretty easy to forget the "set" stage, and not notice (if the kernel is usually giving contiguous buffers, the tests won't catch it). Not sure what else to do at this stage, though. IIUC, the problems you're grappling with right now are on this path. However, I suspect we could hit this problem on the other path (guest Tx) as well: that would be if the guest gives us an outbound frame in multiple discontiguous buffers. For that case we do want to linearise the sections we need to parse, but extending IOV_REMOVE_HEADER() isn't enough. To handle this case we need to extend the packet pool stuff to cope with discontiguous frames. It would be nice, of course, if we can share at least some of the logic between the two paths, but how to make an interface that works for that isn't really clear to me yet. -- David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson