Commit fa8df343 authored by David Howells's avatar David Howells Committed by Jakub Kicinski
Browse files

scsi: iscsi_tcp: Use sendmsg(MSG_SPLICE_PAGES) rather than sendpage



Use sendmsg() with MSG_SPLICE_PAGES rather than sendpage.  This allows
multiple pages and multipage folios to be passed through.

Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
Reviewed-by: default avatarMike Christie <michael.christie@oracle.com>
cc: Lee Duncan <lduncan@suse.com>
cc: Chris Leech <cleech@redhat.com>
cc: "James E.J. Bottomley" <jejb@linux.ibm.com>
cc: "Martin K. Petersen" <martin.petersen@oracle.com>
cc: Jens Axboe <axboe@kernel.dk>
cc: Matthew Wilcox <willy@infradead.org>
cc: Al Viro <viro@zeniv.linux.org.uk>
cc: open-iscsi@googlegroups.com
Link: https://lore.kernel.org/r/20230623225513.2732256-12-dhowells@redhat.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent eeac7405
Loading
Loading
Loading
Loading
+10 −16
Original line number Diff line number Diff line
@@ -301,35 +301,32 @@ static int iscsi_sw_tcp_xmit_segment(struct iscsi_tcp_conn *tcp_conn,

	while (!iscsi_tcp_segment_done(tcp_conn, segment, 0, r)) {
		struct scatterlist *sg;
		struct msghdr msg = {};
		struct bio_vec bv;
		unsigned int offset, copy;
		int flags = 0;

		r = 0;
		offset = segment->copied;
		copy = segment->size - offset;

		if (segment->total_copied + segment->size < segment->total_size)
			flags |= MSG_MORE | MSG_SENDPAGE_NOTLAST;
			msg.msg_flags |= MSG_MORE;

		if (tcp_sw_conn->queue_recv)
			flags |= MSG_DONTWAIT;
			msg.msg_flags |= MSG_DONTWAIT;

		/* Use sendpage if we can; else fall back to sendmsg */
		if (!segment->data) {
			if (!tcp_conn->iscsi_conn->datadgst_en)
				msg.msg_flags |= MSG_SPLICE_PAGES;
			sg = segment->sg;
			offset += segment->sg_offset + sg->offset;
			r = tcp_sw_conn->sendpage(sk, sg_page(sg), offset,
						  copy, flags);
			bvec_set_page(&bv, sg_page(sg), copy, offset);
		} else {
			struct msghdr msg = { .msg_flags = flags };
			struct kvec iov = {
				.iov_base = segment->data + offset,
				.iov_len = copy
			};

			r = kernel_sendmsg(sk, &msg, &iov, 1, copy);
			bvec_set_virt(&bv, segment->data + offset, copy);
		}
		iov_iter_bvec(&msg.msg_iter, ITER_SOURCE, &bv, 1, copy);

		r = sock_sendmsg(sk, &msg);
		if (r < 0) {
			iscsi_tcp_segment_unmap(segment);
			return r;
@@ -746,7 +743,6 @@ iscsi_sw_tcp_conn_bind(struct iscsi_cls_session *cls_session,
	sock_no_linger(sk);

	iscsi_sw_tcp_conn_set_callbacks(conn);
	tcp_sw_conn->sendpage = tcp_sw_conn->sock->ops->sendpage;
	/*
	 * set receive state machine into initial state
	 */
@@ -777,8 +773,6 @@ static int iscsi_sw_tcp_conn_set_param(struct iscsi_cls_conn *cls_conn,
			return -ENOTCONN;
		}
		iscsi_set_param(cls_conn, param, buf, buflen);
		tcp_sw_conn->sendpage = conn->datadgst_en ?
			sock_no_sendpage : tcp_sw_conn->sock->ops->sendpage;
		mutex_unlock(&tcp_sw_conn->sock_lock);
		break;
	case ISCSI_PARAM_MAX_R2T:
+0 −2
Original line number Diff line number Diff line
@@ -47,8 +47,6 @@ struct iscsi_sw_tcp_conn {
	/* MIB custom statistics */
	uint32_t		sendpage_failures_cnt;
	uint32_t		discontiguous_hdr_cnt;

	ssize_t (*sendpage)(struct socket *, struct page *, int, size_t, int);
};

struct iscsi_sw_tcp_host {