Hi Pavel, >>> static int io_sendmsg_copy_hdr(struct io_kiocb *req, >>> struct io_async_msghdr *iomsg) >>> { >>> - iomsg->iov = iomsg->fast_iov; >>> iomsg->msg.msg_name = &iomsg->addr; >>> + iomsg->free_iov = iomsg->fast_iov; >> >> Why this? Isn't the idea of this patch that free_iov is never == fast_iov? > > That's a part of __import_iovec() and sendmsg_copy_msghdr() API, you pass > fast_iov as such and get back NULL or a newly allocated one in it. I think that should at least get a comment to make this clear and maybe a temporary variable like this: tmp_iov = iomsg->fast_iov; __import_iovec(..., &tmp_iov, ...); iomsg->free_iov = tmp_iov; >>> @@ -4872,8 +4867,8 @@ static int io_recvmsg(struct io_kiocb *req, bool force_nonblock, >>> >>> if (req->flags & REQ_F_BUFFER_SELECTED) >>> cflags = io_put_recv_kbuf(req); >>> - if (kmsg->iov != kmsg->fast_iov) >>> - kfree(kmsg->iov); >>> + if (kmsg->free_iov) >>> + kfree(kmsg->free_iov); >> >> kfree() handles NULL, or is this a hot path and we want to avoid a function call? > > Yes, the hot path here is not having iov allocated, and Jens told before > that he had observed overhead for a similar place in io_[read,write]. Ok, a comment would also help here... metze