Browse Source

lustre: switch struct ksock_conn to iov_iter

Merge ksnc_rx_{no_wanted,iov,kiov,niov,nkiov} into a single iov_iter
(ksnc_rx_to).

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Al Viro 8 years ago
parent
commit
33ec9c5cae

+ 2 - 2
drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c

@@ -1688,10 +1688,10 @@ ksocknal_destroy_conn(struct ksock_conn *conn)
 	case SOCKNAL_RX_LNET_PAYLOAD:
 		last_rcv = conn->ksnc_rx_deadline -
 			   cfs_time_seconds(*ksocknal_tunables.ksnd_timeout);
-		CERROR("Completing partial receive from %s[%d], ip %pI4h:%d, with error, wanted: %d, left: %d, last alive is %ld secs ago\n",
+		CERROR("Completing partial receive from %s[%d], ip %pI4h:%d, with error, wanted: %zd, left: %d, last alive is %ld secs ago\n",
 		       libcfs_id2str(conn->ksnc_peer->ksnp_id), conn->ksnc_type,
 		       &conn->ksnc_ipaddr, conn->ksnc_port,
-		       conn->ksnc_rx_nob_wanted, conn->ksnc_rx_nob_left,
+		       iov_iter_count(&conn->ksnc_rx_to), conn->ksnc_rx_nob_left,
 		       cfs_duration_sec(cfs_time_sub(cfs_time_current(),
 						     last_rcv)));
 		lnet_finalize(conn->ksnc_peer->ksnp_ni,

+ 1 - 5
drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h

@@ -357,11 +357,7 @@ struct ksock_conn {
 	__u8               ksnc_rx_scheduled; /* being progressed */
 	__u8               ksnc_rx_state;     /* what is being read */
 	int                ksnc_rx_nob_left;  /* # bytes to next hdr/body */
-	int                ksnc_rx_nob_wanted;/* bytes actually wanted */
-	int                ksnc_rx_niov;      /* # iovec frags */
-	struct kvec        *ksnc_rx_iov;      /* the iovec frags */
-	int                ksnc_rx_nkiov;     /* # page frags */
-	struct bio_vec		*ksnc_rx_kiov;	/* the page frags */
+	struct iov_iter    ksnc_rx_to;		/* copy destination */
 	union ksock_rxiovspace ksnc_rx_iov_space; /* space for frag descriptors */
 	__u32              ksnc_rx_csum;      /* partial checksum for incoming
 					       * data

+ 33 - 90
drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c

@@ -251,14 +251,11 @@ ksocknal_transmit(struct ksock_conn *conn, struct ksock_tx *tx)
 static int
 ksocknal_recv_iov(struct ksock_conn *conn)
 {
-	struct kvec *iov = conn->ksnc_rx_iov;
 	int nob;
 	int rc;
 
-	LASSERT(conn->ksnc_rx_niov > 0);
-
 	/*
-	 * Never touch conn->ksnc_rx_iov or change connection
+	 * Never touch conn->ksnc_rx_to or change connection
 	 * status inside ksocknal_lib_recv_iov
 	 */
 	rc = ksocknal_lib_recv_iov(conn);
@@ -275,22 +272,11 @@ ksocknal_recv_iov(struct ksock_conn *conn)
 	mb();		       /* order with setting rx_started */
 	conn->ksnc_rx_started = 1;
 
-	conn->ksnc_rx_nob_wanted -= nob;
 	conn->ksnc_rx_nob_left -= nob;
 
-	do {
-		LASSERT(conn->ksnc_rx_niov > 0);
-
-		if (nob < (int)iov->iov_len) {
-			iov->iov_len -= nob;
-			iov->iov_base += nob;
-			return -EAGAIN;
-		}
-
-		nob -= iov->iov_len;
-		conn->ksnc_rx_iov = ++iov;
-		conn->ksnc_rx_niov--;
-	} while (nob);
+	iov_iter_advance(&conn->ksnc_rx_to, nob);
+	if (iov_iter_count(&conn->ksnc_rx_to))
+		return -EAGAIN;
 
 	return rc;
 }
@@ -298,14 +284,11 @@ ksocknal_recv_iov(struct ksock_conn *conn)
 static int
 ksocknal_recv_kiov(struct ksock_conn *conn)
 {
-	struct bio_vec *kiov = conn->ksnc_rx_kiov;
 	int nob;
 	int rc;
 
-	LASSERT(conn->ksnc_rx_nkiov > 0);
-
 	/*
-	 * Never touch conn->ksnc_rx_kiov or change connection
+	 * Never touch conn->ksnc_rx_to or change connection
 	 * status inside ksocknal_lib_recv_iov
 	 */
 	rc = ksocknal_lib_recv_kiov(conn);
@@ -322,22 +305,10 @@ ksocknal_recv_kiov(struct ksock_conn *conn)
 	mb();		       /* order with setting rx_started */
 	conn->ksnc_rx_started = 1;
 
-	conn->ksnc_rx_nob_wanted -= nob;
 	conn->ksnc_rx_nob_left -= nob;
-
-	do {
-		LASSERT(conn->ksnc_rx_nkiov > 0);
-
-		if (nob < (int)kiov->bv_len) {
-			kiov->bv_offset += nob;
-			kiov->bv_len -= nob;
-			return -EAGAIN;
-		}
-
-		nob -= kiov->bv_len;
-		conn->ksnc_rx_kiov = ++kiov;
-		conn->ksnc_rx_nkiov--;
-	} while (nob);
+	iov_iter_advance(&conn->ksnc_rx_to, nob);
+	if (iov_iter_count(&conn->ksnc_rx_to))
+		return -EAGAIN;
 
 	return 1;
 }
@@ -347,7 +318,7 @@ ksocknal_receive(struct ksock_conn *conn)
 {
 	/*
 	 * Return 1 on success, 0 on EOF, < 0 on error.
-	 * Caller checks ksnc_rx_nob_wanted to determine
+	 * Caller checks ksnc_rx_to to determine
 	 * progress/completion.
 	 */
 	int rc;
@@ -364,7 +335,7 @@ ksocknal_receive(struct ksock_conn *conn)
 	}
 
 	for (;;) {
-		if (conn->ksnc_rx_niov)
+		if (conn->ksnc_rx_to.type & ITER_KVEC)
 			rc = ksocknal_recv_iov(conn);
 		else
 			rc = ksocknal_recv_kiov(conn);
@@ -382,7 +353,7 @@ ksocknal_receive(struct ksock_conn *conn)
 
 		/* Completed a fragment */
 
-		if (!conn->ksnc_rx_nob_wanted) {
+		if (!iov_iter_count(&conn->ksnc_rx_to)) {
 			rc = 1;
 			break;
 		}
@@ -1050,6 +1021,7 @@ int
 ksocknal_new_packet(struct ksock_conn *conn, int nob_to_skip)
 {
 	static char ksocknal_slop_buffer[4096];
+	struct kvec *kvec = (struct kvec *)&conn->ksnc_rx_iov_space;
 
 	int nob;
 	unsigned int niov;
@@ -1070,32 +1042,26 @@ ksocknal_new_packet(struct ksock_conn *conn, int nob_to_skip)
 		case  KSOCK_PROTO_V2:
 		case  KSOCK_PROTO_V3:
 			conn->ksnc_rx_state = SOCKNAL_RX_KSM_HEADER;
-			conn->ksnc_rx_iov = (struct kvec *)&conn->ksnc_rx_iov_space;
-			conn->ksnc_rx_iov[0].iov_base = &conn->ksnc_msg;
-
-			conn->ksnc_rx_nob_wanted = offsetof(struct ksock_msg, ksm_u);
+			kvec->iov_base = &conn->ksnc_msg;
+			kvec->iov_len = offsetof(struct ksock_msg, ksm_u);
 			conn->ksnc_rx_nob_left = offsetof(struct ksock_msg, ksm_u);
-			conn->ksnc_rx_iov[0].iov_len = offsetof(struct ksock_msg, ksm_u);
+			iov_iter_kvec(&conn->ksnc_rx_to, READ|ITER_KVEC, kvec,
+					1, offsetof(struct ksock_msg, ksm_u));
 			break;
 
 		case KSOCK_PROTO_V1:
 			/* Receiving bare struct lnet_hdr */
 			conn->ksnc_rx_state = SOCKNAL_RX_LNET_HEADER;
-			conn->ksnc_rx_nob_wanted = sizeof(struct lnet_hdr);
+			kvec->iov_base = &conn->ksnc_msg.ksm_u.lnetmsg;
+			kvec->iov_len = sizeof(struct lnet_hdr);
 			conn->ksnc_rx_nob_left = sizeof(struct lnet_hdr);
-
-			conn->ksnc_rx_iov = (struct kvec *)&conn->ksnc_rx_iov_space;
-			conn->ksnc_rx_iov[0].iov_base = &conn->ksnc_msg.ksm_u.lnetmsg;
-			conn->ksnc_rx_iov[0].iov_len = sizeof(struct lnet_hdr);
+			iov_iter_kvec(&conn->ksnc_rx_to, READ|ITER_KVEC, kvec,
+					1, sizeof(struct lnet_hdr));
 			break;
 
 		default:
 			LBUG();
 		}
-		conn->ksnc_rx_niov = 1;
-
-		conn->ksnc_rx_kiov = NULL;
-		conn->ksnc_rx_nkiov = 0;
 		conn->ksnc_rx_csum = ~0;
 		return 1;
 	}
@@ -1106,15 +1072,14 @@ ksocknal_new_packet(struct ksock_conn *conn, int nob_to_skip)
 	 */
 	conn->ksnc_rx_state = SOCKNAL_RX_SLOP;
 	conn->ksnc_rx_nob_left = nob_to_skip;
-	conn->ksnc_rx_iov = (struct kvec *)&conn->ksnc_rx_iov_space;
 	skipped = 0;
 	niov = 0;
 
 	do {
 		nob = min_t(int, nob_to_skip, sizeof(ksocknal_slop_buffer));
 
-		conn->ksnc_rx_iov[niov].iov_base = ksocknal_slop_buffer;
-		conn->ksnc_rx_iov[niov].iov_len  = nob;
+		kvec[niov].iov_base = ksocknal_slop_buffer;
+		kvec[niov].iov_len  = nob;
 		niov++;
 		skipped += nob;
 		nob_to_skip -= nob;
@@ -1122,16 +1087,14 @@ ksocknal_new_packet(struct ksock_conn *conn, int nob_to_skip)
 	} while (nob_to_skip &&    /* mustn't overflow conn's rx iov */
 		 niov < sizeof(conn->ksnc_rx_iov_space) / sizeof(struct iovec));
 
-	conn->ksnc_rx_niov = niov;
-	conn->ksnc_rx_kiov = NULL;
-	conn->ksnc_rx_nkiov = 0;
-	conn->ksnc_rx_nob_wanted = skipped;
+	iov_iter_kvec(&conn->ksnc_rx_to, READ|ITER_KVEC, kvec, niov, skipped);
 	return 0;
 }
 
 static int
 ksocknal_process_receive(struct ksock_conn *conn)
 {
+	struct kvec *kvec = (struct kvec *)&conn->ksnc_rx_iov_space;
 	struct lnet_hdr *lhdr;
 	struct lnet_process_id *id;
 	int rc;
@@ -1145,7 +1108,7 @@ ksocknal_process_receive(struct ksock_conn *conn)
 		conn->ksnc_rx_state == SOCKNAL_RX_LNET_HEADER ||
 		conn->ksnc_rx_state == SOCKNAL_RX_SLOP);
  again:
-	if (conn->ksnc_rx_nob_wanted) {
+	if (iov_iter_count(&conn->ksnc_rx_to)) {
 		rc = ksocknal_receive(conn);
 
 		if (rc <= 0) {
@@ -1170,7 +1133,7 @@ ksocknal_process_receive(struct ksock_conn *conn)
 			return (!rc ? -ESHUTDOWN : rc);
 		}
 
-		if (conn->ksnc_rx_nob_wanted) {
+		if (iov_iter_count(&conn->ksnc_rx_to)) {
 			/* short read */
 			return -EAGAIN;
 		}
@@ -1233,16 +1196,13 @@ ksocknal_process_receive(struct ksock_conn *conn)
 		}
 
 		conn->ksnc_rx_state = SOCKNAL_RX_LNET_HEADER;
-		conn->ksnc_rx_nob_wanted = sizeof(struct ksock_lnet_msg);
 		conn->ksnc_rx_nob_left = sizeof(struct ksock_lnet_msg);
 
-		conn->ksnc_rx_iov = (struct kvec *)&conn->ksnc_rx_iov_space;
-		conn->ksnc_rx_iov[0].iov_base = &conn->ksnc_msg.ksm_u.lnetmsg;
-		conn->ksnc_rx_iov[0].iov_len = sizeof(struct ksock_lnet_msg);
+		kvec->iov_base = &conn->ksnc_msg.ksm_u.lnetmsg;
+		kvec->iov_len = sizeof(struct ksock_lnet_msg);
 
-		conn->ksnc_rx_niov = 1;
-		conn->ksnc_rx_kiov = NULL;
-		conn->ksnc_rx_nkiov = 0;
+		iov_iter_kvec(&conn->ksnc_rx_to, READ|ITER_KVEC, kvec,
+				1, sizeof(struct ksock_lnet_msg));
 
 		goto again;     /* read lnet header now */
 
@@ -1344,26 +1304,9 @@ ksocknal_recv(struct lnet_ni *ni, void *private, struct lnet_msg *msg,
 	LASSERT(to->nr_segs <= LNET_MAX_IOV);
 
 	conn->ksnc_cookie = msg;
-	conn->ksnc_rx_nob_wanted = iov_iter_count(to);
 	conn->ksnc_rx_nob_left = rlen;
 
-	if (to->type & ITER_KVEC) {
-		conn->ksnc_rx_nkiov = 0;
-		conn->ksnc_rx_kiov = NULL;
-		conn->ksnc_rx_iov = conn->ksnc_rx_iov_space.iov;
-		conn->ksnc_rx_niov =
-			lnet_extract_iov(LNET_MAX_IOV, conn->ksnc_rx_iov,
-					 to->nr_segs, to->kvec,
-					 to->iov_offset, iov_iter_count(to));
-	} else {
-		conn->ksnc_rx_niov = 0;
-		conn->ksnc_rx_iov = NULL;
-		conn->ksnc_rx_kiov = conn->ksnc_rx_iov_space.kiov;
-		conn->ksnc_rx_nkiov =
-			lnet_extract_kiov(LNET_MAX_IOV, conn->ksnc_rx_kiov,
-					 to->nr_segs, to->bvec,
-					 to->iov_offset, iov_iter_count(to));
-	}
+	conn->ksnc_rx_to = *to;
 
 	LASSERT(conn->ksnc_rx_scheduled);
 
@@ -2328,12 +2271,12 @@ ksocknal_find_timed_out_conn(struct ksock_peer *peer)
 				     conn->ksnc_rx_deadline)) {
 			/* Timed out incomplete incoming message */
 			ksocknal_conn_addref(conn);
-			CNETERR("Timeout receiving from %s (%pI4h:%d), state %d wanted %d left %d\n",
+			CNETERR("Timeout receiving from %s (%pI4h:%d), state %d wanted %zd left %d\n",
 				libcfs_id2str(peer->ksnp_id),
 				&conn->ksnc_ipaddr,
 				conn->ksnc_port,
 				conn->ksnc_rx_state,
-				conn->ksnc_rx_nob_wanted,
+				iov_iter_count(&conn->ksnc_rx_to),
 				conn->ksnc_rx_nob_left);
 			return conn;
 		}

+ 16 - 24
drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib.c

@@ -164,26 +164,19 @@ ksocknal_lib_eager_ack(struct ksock_conn *conn)
 int
 ksocknal_lib_recv_iov(struct ksock_conn *conn)
 {
-	unsigned int niov = conn->ksnc_rx_niov;
-	struct kvec *iov = conn->ksnc_rx_iov;
+	unsigned int niov = conn->ksnc_rx_to.nr_segs;
+	const struct iovec *iov = conn->ksnc_rx_to.iov;
 	struct msghdr msg = {
 		.msg_flags = 0
 	};
-	int nob;
 	int i;
 	int rc;
 	int fragnob;
 	int sum;
 	__u32 saved_csum;
+	int off = conn->ksnc_rx_to.iov_offset;
 
-	LASSERT(niov > 0);
-
-	for (nob = i = 0; i < niov; i++)
-		nob += iov[i].iov_len;
-
-	LASSERT(nob <= conn->ksnc_rx_nob_wanted);
-
-	iov_iter_kvec(&msg.msg_iter, READ | ITER_KVEC, iov, niov, nob);
+	msg.msg_iter = conn->ksnc_rx_to;
 	rc = sock_recvmsg(conn->ksnc_sock, &msg, MSG_DONTWAIT);
 
 	saved_csum = 0;
@@ -197,13 +190,14 @@ ksocknal_lib_recv_iov(struct ksock_conn *conn)
 		for (i = 0, sum = rc; sum > 0; i++, sum -= fragnob) {
 			LASSERT(i < niov);
 
-			fragnob = iov[i].iov_len;
+			fragnob = iov[i].iov_len - off;
 			if (fragnob > sum)
 				fragnob = sum;
 
 			conn->ksnc_rx_csum = crc32_le(conn->ksnc_rx_csum,
-						      iov[i].iov_base,
+						      iov[i].iov_base + off,
 						      fragnob);
+			off = 0;
 		}
 		conn->ksnc_msg.ksm_csum = saved_csum;
 	}
@@ -214,32 +208,29 @@ ksocknal_lib_recv_iov(struct ksock_conn *conn)
 int
 ksocknal_lib_recv_kiov(struct ksock_conn *conn)
 {
-	unsigned int niov = conn->ksnc_rx_nkiov;
-	struct bio_vec *kiov = conn->ksnc_rx_kiov;
+	unsigned int niov = conn->ksnc_rx_to.nr_segs;
+	const struct bio_vec *kiov = conn->ksnc_rx_to.bvec;
+	int off = conn->ksnc_rx_to.iov_offset;
 	struct msghdr msg = {
 		.msg_flags = 0
 	};
-	int nob;
 	int i;
 	int rc;
 	void *base;
 	int sum;
 	int fragnob;
 
-	for (nob = i = 0; i < niov; i++)
-		nob += kiov[i].bv_len;
-
-	LASSERT(nob <= conn->ksnc_rx_nob_wanted);
-
-	iov_iter_bvec(&msg.msg_iter, READ | ITER_BVEC, kiov, niov, nob);
+	msg.msg_iter = conn->ksnc_rx_to;
 	rc = sock_recvmsg(conn->ksnc_sock, &msg, MSG_DONTWAIT);
+	if (rc <= 0)
+		return rc;
 
 	if (conn->ksnc_msg.ksm_csum) {
 		for (i = 0, sum = rc; sum > 0; i++, sum -= fragnob) {
 			LASSERT(i < niov);
 
-			base = kmap(kiov[i].bv_page) + kiov[i].bv_offset;
-			fragnob = kiov[i].bv_len;
+			base = kmap(kiov[i].bv_page) + kiov[i].bv_offset + off;
+			fragnob = kiov[i].bv_len - off;
 			if (fragnob > sum)
 				fragnob = sum;
 
@@ -247,6 +238,7 @@ ksocknal_lib_recv_kiov(struct ksock_conn *conn)
 						      base, fragnob);
 
 			kunmap(kiov[i].bv_page);
+			off = 0;
 		}
 	}
 	return rc;