Re: [PATCH net-next v2 17/17] net: Kill MSG_SENDPAGE_NOTLAST
David Howells <[email protected]> Mon, 19 Jun 2023 12:05:27 +0000
| Newsgroups | org.kernel.vger.dccp,dev.linux.lists.mptcp,dev.linux.lists.virtualization,org.kernel.vger.bpf,org.kernel.vger.linux-arm-msm,org.kernel.vger.linux-can,org.kernel.vger.linux-crypto,org.kernel.vger.linux-doc,org.kernel.vger.linux-hams,org.kernel.vger.linux-kernel,org.kernel.vger.linux-perf-users,org.kernel.vger.linux-rdma,org.kernel.vger.linux-sctp,org.kernel.vger.linux-wpan,org.kernel.vger.linux-x25,org.kernel.vger.netdev,org.kvack.linux-mm |
|---|---|
| Message-ID | <[email protected]> |
Willem de Bruijn <[email protected]> wrote: > Is it intentional to add MSG_MORE here in this patch? > > I do see that patch 3 removes this branch: Yeah. I think I may have tcp_bpf a bit wrong with regard to handling MSG_MORE. How about the attached version of tcp_bpf_push()? I wonder if it's save to move the setting of MSG_SENDPAGE_NOPOLICY out of the loop as I've done here. The caller holds the socket lock. Also, I'm not sure whether to take account of apply/apply_bytes when setting MSG_MORE mid-message, or whether to just go on whether we've reached sge->length yet. (I'm not sure exactly how tcp_bpf works). David --- static int tcp_bpf_push(struct sock *sk, struct sk_msg *msg, u32 apply_bytes, int flags, bool uncharge) { bool apply = apply_bytes; struct scatterlist *sge; struct page *page; int size, ret = 0; u32 off; flags |= MSG_SPLICE_PAGES; if (tls_sw_has_ctx_tx(sk)) msghdr.msg_flags |= MSG_SENDPAGE_NOPOLICY; while (1) { struct msghdr msghdr = {}; struct bio_vec bvec; sge = sk_msg_elem(msg, msg->sg.start); size = (apply && apply_bytes < sge->length) ? apply_bytes : sge->length; off = sge->offset; page = sg_page(sge); tcp_rate_check_app_limited(sk); retry: msghdr.msg_flags = flags; /* Determine if we need to set MSG_MORE. */ if (!(msghdr.msg_flags & MSG_MORE)) { if (apply && size < apply_bytes) msghdr.msg_flags |= MSG_MORE; else if (!apply && size < sge->length && msg->sg.start != msg->sg.end) msghdr.msg_flags |= MSG_MORE; } bvec_set_page(&bvec, page, size, off); iov_iter_bvec(&msghdr.msg_iter, ITER_SOURCE, &bvec, 1, size); ret = tcp_sendmsg_locked(sk, &msghdr, size); if (ret <= 0) return ret; if (apply) apply_bytes -= ret; msg->sg.size -= ret; sge->offset += ret; sge->length -= ret; if (uncharge) sk_mem_uncharge(sk, ret); if (ret != size) { size -= ret; off += ret; goto retry; } if (!sge->length) { put_page(page); sk_msg_iter_next(msg, start); sg_init_table(sge, 1); if (msg->sg.start = msg->sg.end) break; } if (apply && !apply_bytes) break; } return 0; }