Hello, How about use WARN_ONCE() just in case to catch any unexpected changes in the future? Though page array is not used in bvec now, we can't guarantee it won't change in the future.
Wrt whether it is necessary to check page ref = 0 here, I have same doubts, I also don't quite understand why it is possible that 0-ref page would end up here, but if that is possible, it should be handled correctly with this patch. BTW, do you think we need to replace iov_iter_get_pages() in do_recv_one_seg() with similar implementation? -----Original Message----- From: Alexey Kuznetsov <kuz...@acronis.com <mailto:kuz...@acronis.com>> Date: Wednesday, 19 April 2023 at 12:09 AM To: Kui Liu <kui....@acronis.com <mailto:kui....@acronis.com>> Cc: Devel <devel@openvz.org <mailto:devel@openvz.org>>, Konstantin Khorenko <khore...@virtuozzo.com <mailto:khore...@virtuozzo.com>> Subject: Re: [Devel] [PATCH RH9] fuse: pcs: do not use sendpage on pages which cannot be sendpaged Hello! Ack. Disgusting at the first sight, but I like this! :-) Indeed, this iterator is our internal thing, we created it ourselves and actually we have no reasons to use dubious spoiled system implementation. One note, formally, BUG_ON is incorrect. We should assert it->iov_offset + i->bvec->bv_offset < PAGE_SIZE. I do not understand this place in system implementation, I have never seen anyone using bvecs in this way, they allow bv_page pointing to array of pages, this looks so scary. But this is our internal iter, so that we may omit assertions. BTW this does not answer my doubts, the problem is not in our code. I do not understand _why_ sendpage_ok is necessary. The check page_count(page) >= 1 wants to tell that get_page on page with 0 refcnt is illegal. But fuse already did get_page at top level, it uses iov_iter_get_pages in fuse_get_user_pages(), so that: 1. If it is not allowed it is already broken by the time the page arrives to us 2. It is impossible to have page_count == 0 in kernel_sendpage, it is grabbed by top level. All this looks as big smelly pile of shit, mainstream not us. :-) On Tue, Apr 18, 2023 at 10:22 PM Kui Liu <kui....@acronis.com <mailto:kui....@acronis.com>> wrote: > > > It looks like the new API iov_iter_get_pages is not safe for use > when trying to get a page from a bvec to be sent by kernel_sendpage(). > So just revert back our own implentation where we check the page > before making get_page(), if the page can't be sendpage, fall back > to copy mode. > > Affects: #PSBM-146821, #PSBM-146846 > https://jira.vzint.dev/browse/PSBM-146821 > <https://jira.vzint.dev/browse/PSBM-146821> > https://jira.vzint.dev/browse/PSBM-146846 > <https://jira.vzint.dev/browse/PSBM-146846> > Signed-off-by: Liu Kui <kui....@acronis.com <mailto:kui....@acronis.com>> > --- > fs/fuse/kio/pcs/pcs_sock_io.c | 28 ++++++++++++++++++++++------ > 1 file changed, 22 insertions(+), 6 deletions(-) > > diff --git a/fs/fuse/kio/pcs/pcs_sock_io.c b/fs/fuse/kio/pcs/pcs_sock_io.c > index 552b82ab398b..20f088d36d6d 100644 > --- a/fs/fuse/kio/pcs/pcs_sock_io.c > +++ b/fs/fuse/kio/pcs/pcs_sock_io.c > @@ -143,16 +143,32 @@ static int do_send_one_seg(struct socket *sock, struct > iov_iter *it, size_t left > } > > if (iov_iter_is_bvec(it)) { > - /* Zerocopy */ > size_t offset; > ssize_t len; > struct page *page; > > - len = iov_iter_get_pages(it, &page, size, 1, &offset); > - BUG_ON(len <= 0); > - > - ret = kernel_sendpage(sock, page, offset, len, flags); > - put_page(page); > + /* Only support single page bvec here */ > + BUG_ON(it->bvec->bv_len > PAGE_SIZE); > + > + page = it->bvec->bv_page; > + offset = it->bvec->bv_offset + it->iov_offset; > + len = min(size, it->bvec->bv_len - it->iov_offset); > + > + if (sendpage_ok(page)) { > + /* Zero copy */ > + get_page(page); > + ret = kernel_sendpage(sock, page, offset, len, flags); > + put_page(page); > + } else { > + /* Fall back to copy mode */ > + struct msghdr msg = { .msg_flags = flags }; > + struct kvec kv; > + > + kv.iov_base = kmap(page) + offset; > + kv.iov_len = len; > + ret = kernel_sendmsg(sock, &msg, &kv, 1, size); > + kunmap(page); > + } > } > > out: > -- > 2.32.0 (Apple Git-132) > > -----Original Message----- > From: Alexey Kuznetsov <kuz...@acronis.com <mailto:kuz...@acronis.com> > <mailto:kuz...@acronis.com <mailto:kuz...@acronis.com>>> > Date: Monday, 17 April 2023 at 10:31 PM > To: Devel <devel@openvz.org <mailto:devel@openvz.org> > <mailto:devel@openvz.org <mailto:devel@openvz.org>>>, Konstantin Khorenko > <khore...@virtuozzo.com <mailto:khore...@virtuozzo.com> > <mailto:khore...@virtuozzo.com <mailto:khore...@virtuozzo.com>>>, Kui Liu > <kui....@acronis.com <mailto:kui....@acronis.com> <mailto:kui....@acronis.com > <mailto:kui....@acronis.com>>> > Subject: [PATCH RH9] fuse: pcs: do not use sendpage on pages which cannot be > sendpaged > > > Use the same approach as in iscsi iscsi_tcp_segment_map() which makes > the same operation > in the same context. > > > In vz7 we added iov_iter_get_pages() infrastructure ourselves and we > did it in safe way. > We checked page before doing any manipulations on it right in core of > iov_iter_get_pages() > and terminated iov_iter_get_pages() if the page looked dubious. We > cannot make this now because > this function is used in many places over kernel and not all the > places are sensitive > to origin of pages but all of them definitely will crash if > iov_iter_get_pages() returns error. > > > This patch will work for now. I still believe this place deserves > further investigation. > It smells like mainstream could be wrong. Look at my comment in code > for the reasons of doubts. > > > Affects: #PSBM-146821, #PSBM-146846 > https://jira.vzint.dev/browse/PSBM-146821 > <https://jira.vzint.dev/browse/PSBM-146821> > <https://jira.vzint.dev/browse/PSBM-146821> > <https://jira.vzint.dev/browse/PSBM-146821>> > https://jira.vzint.dev/browse/PSBM-146846 > <https://jira.vzint.dev/browse/PSBM-146846> > <https://jira.vzint.dev/browse/PSBM-146846> > <https://jira.vzint.dev/browse/PSBM-146846>> > > > Signed-off-by: Alexey Kuznetsov <kuz...@acronis.com > <mailto:kuz...@acronis.com> <mailto:kuz...@acronis.com > <mailto:kuz...@acronis.com>>> > > > > _______________________________________________ > Devel mailing list > Devel@openvz.org <mailto:Devel@openvz.org> > https://lists.openvz.org/mailman/listinfo/devel > <https://lists.openvz.org/mailman/listinfo/devel> _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel