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? > @@ -4704,10 +4703,11 @@ static int __io_recvmsg_copy_hdr(struct io_kiocb *req, > if (copy_from_user(iomsg->fast_iov, uiov, sizeof(*uiov))) > return -EFAULT; > sr->len = iomsg->fast_iov[0].iov_len; > - iomsg->iov = NULL; > + iomsg->free_iov = NULL; > } else { > + iomsg->free_iov = iomsg->fast_iov; The same here... > ret = __import_iovec(READ, uiov, iov_len, UIO_FASTIOV, > - &iomsg->iov, &iomsg->msg.msg_iter, > + &iomsg->free_iov, &iomsg->msg.msg_iter, > false); > if (ret > 0) > ret = 0; > @@ -4746,10 +4746,11 @@ static int __io_compat_recvmsg_copy_hdr(struct io_kiocb *req, > if (clen < 0) > return -EINVAL; > sr->len = clen; > - iomsg->iov = NULL; > + iomsg->free_iov = NULL; > } else { > + iomsg->free_iov = iomsg->fast_iov; And here... > ret = __import_iovec(READ, (struct iovec __user *)uiov, len, > - UIO_FASTIOV, &iomsg->iov, > + UIO_FASTIOV, &iomsg->free_iov, > &iomsg->msg.msg_iter, true); > if (ret < 0) > return ret; > @@ -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? metze