|
@@ -250,66 +250,16 @@ ksocknal_transmit(struct ksock_conn *conn, struct ksock_tx *tx)
|
|
}
|
|
}
|
|
|
|
|
|
static int
|
|
static int
|
|
-ksocknal_recv_iov(struct ksock_conn *conn)
|
|
|
|
|
|
+ksocknal_recv_iter(struct ksock_conn *conn)
|
|
{
|
|
{
|
|
- struct kvec *iov = conn->ksnc_rx_iov;
|
|
|
|
int nob;
|
|
int nob;
|
|
int rc;
|
|
int rc;
|
|
|
|
|
|
- LASSERT(conn->ksnc_rx_niov > 0);
|
|
|
|
-
|
|
|
|
- /*
|
|
|
|
- * Never touch conn->ksnc_rx_iov or change connection
|
|
|
|
- * status inside ksocknal_lib_recv_iov
|
|
|
|
- */
|
|
|
|
- rc = ksocknal_lib_recv_iov(conn);
|
|
|
|
-
|
|
|
|
- if (rc <= 0)
|
|
|
|
- return rc;
|
|
|
|
-
|
|
|
|
- /* received something... */
|
|
|
|
- nob = rc;
|
|
|
|
-
|
|
|
|
- conn->ksnc_peer->ksnp_last_alive = cfs_time_current();
|
|
|
|
- conn->ksnc_rx_deadline =
|
|
|
|
- cfs_time_shift(*ksocknal_tunables.ksnd_timeout);
|
|
|
|
- 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);
|
|
|
|
-
|
|
|
|
- return rc;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-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
|
|
|
|
- * status inside ksocknal_lib_recv_iov
|
|
|
|
|
|
+ * Never touch conn->ksnc_rx_to or change connection
|
|
|
|
+ * status inside ksocknal_lib_recv
|
|
*/
|
|
*/
|
|
- rc = ksocknal_lib_recv_kiov(conn);
|
|
|
|
|
|
+ rc = ksocknal_lib_recv(conn);
|
|
|
|
|
|
if (rc <= 0)
|
|
if (rc <= 0)
|
|
return rc;
|
|
return rc;
|
|
@@ -323,22 +273,11 @@ ksocknal_recv_kiov(struct ksock_conn *conn)
|
|
mb(); /* order with setting rx_started */
|
|
mb(); /* order with setting rx_started */
|
|
conn->ksnc_rx_started = 1;
|
|
conn->ksnc_rx_started = 1;
|
|
|
|
|
|
- conn->ksnc_rx_nob_wanted -= nob;
|
|
|
|
conn->ksnc_rx_nob_left -= 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;
|
|
return 1;
|
|
}
|
|
}
|
|
@@ -348,7 +287,7 @@ ksocknal_receive(struct ksock_conn *conn)
|
|
{
|
|
{
|
|
/*
|
|
/*
|
|
* Return 1 on success, 0 on EOF, < 0 on error.
|
|
* 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.
|
|
* progress/completion.
|
|
*/
|
|
*/
|
|
int rc;
|
|
int rc;
|
|
@@ -365,11 +304,7 @@ ksocknal_receive(struct ksock_conn *conn)
|
|
}
|
|
}
|
|
|
|
|
|
for (;;) {
|
|
for (;;) {
|
|
- if (conn->ksnc_rx_niov)
|
|
|
|
- rc = ksocknal_recv_iov(conn);
|
|
|
|
- else
|
|
|
|
- rc = ksocknal_recv_kiov(conn);
|
|
|
|
-
|
|
|
|
|
|
+ rc = ksocknal_recv_iter(conn);
|
|
if (rc <= 0) {
|
|
if (rc <= 0) {
|
|
/* error/EOF or partial receive */
|
|
/* error/EOF or partial receive */
|
|
if (rc == -EAGAIN) {
|
|
if (rc == -EAGAIN) {
|
|
@@ -383,7 +318,7 @@ ksocknal_receive(struct ksock_conn *conn)
|
|
|
|
|
|
/* Completed a fragment */
|
|
/* Completed a fragment */
|
|
|
|
|
|
- if (!conn->ksnc_rx_nob_wanted) {
|
|
|
|
|
|
+ if (!iov_iter_count(&conn->ksnc_rx_to)) {
|
|
rc = 1;
|
|
rc = 1;
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
@@ -1051,6 +986,7 @@ int
|
|
ksocknal_new_packet(struct ksock_conn *conn, int nob_to_skip)
|
|
ksocknal_new_packet(struct ksock_conn *conn, int nob_to_skip)
|
|
{
|
|
{
|
|
static char ksocknal_slop_buffer[4096];
|
|
static char ksocknal_slop_buffer[4096];
|
|
|
|
+ struct kvec *kvec = (struct kvec *)&conn->ksnc_rx_iov_space;
|
|
|
|
|
|
int nob;
|
|
int nob;
|
|
unsigned int niov;
|
|
unsigned int niov;
|
|
@@ -1071,32 +1007,26 @@ ksocknal_new_packet(struct ksock_conn *conn, int nob_to_skip)
|
|
case KSOCK_PROTO_V2:
|
|
case KSOCK_PROTO_V2:
|
|
case KSOCK_PROTO_V3:
|
|
case KSOCK_PROTO_V3:
|
|
conn->ksnc_rx_state = SOCKNAL_RX_KSM_HEADER;
|
|
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_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;
|
|
break;
|
|
|
|
|
|
case KSOCK_PROTO_V1:
|
|
case KSOCK_PROTO_V1:
|
|
/* Receiving bare struct lnet_hdr */
|
|
/* Receiving bare struct lnet_hdr */
|
|
conn->ksnc_rx_state = SOCKNAL_RX_LNET_HEADER;
|
|
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_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;
|
|
break;
|
|
|
|
|
|
default:
|
|
default:
|
|
LBUG();
|
|
LBUG();
|
|
}
|
|
}
|
|
- conn->ksnc_rx_niov = 1;
|
|
|
|
-
|
|
|
|
- conn->ksnc_rx_kiov = NULL;
|
|
|
|
- conn->ksnc_rx_nkiov = 0;
|
|
|
|
conn->ksnc_rx_csum = ~0;
|
|
conn->ksnc_rx_csum = ~0;
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
@@ -1107,15 +1037,14 @@ ksocknal_new_packet(struct ksock_conn *conn, int nob_to_skip)
|
|
*/
|
|
*/
|
|
conn->ksnc_rx_state = SOCKNAL_RX_SLOP;
|
|
conn->ksnc_rx_state = SOCKNAL_RX_SLOP;
|
|
conn->ksnc_rx_nob_left = nob_to_skip;
|
|
conn->ksnc_rx_nob_left = nob_to_skip;
|
|
- conn->ksnc_rx_iov = (struct kvec *)&conn->ksnc_rx_iov_space;
|
|
|
|
skipped = 0;
|
|
skipped = 0;
|
|
niov = 0;
|
|
niov = 0;
|
|
|
|
|
|
do {
|
|
do {
|
|
nob = min_t(int, nob_to_skip, sizeof(ksocknal_slop_buffer));
|
|
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++;
|
|
niov++;
|
|
skipped += nob;
|
|
skipped += nob;
|
|
nob_to_skip -= nob;
|
|
nob_to_skip -= nob;
|
|
@@ -1123,16 +1052,14 @@ ksocknal_new_packet(struct ksock_conn *conn, int nob_to_skip)
|
|
} while (nob_to_skip && /* mustn't overflow conn's rx iov */
|
|
} while (nob_to_skip && /* mustn't overflow conn's rx iov */
|
|
niov < sizeof(conn->ksnc_rx_iov_space) / sizeof(struct iovec));
|
|
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;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
static int
|
|
static int
|
|
ksocknal_process_receive(struct ksock_conn *conn)
|
|
ksocknal_process_receive(struct ksock_conn *conn)
|
|
{
|
|
{
|
|
|
|
+ struct kvec *kvec = (struct kvec *)&conn->ksnc_rx_iov_space;
|
|
struct lnet_hdr *lhdr;
|
|
struct lnet_hdr *lhdr;
|
|
struct lnet_process_id *id;
|
|
struct lnet_process_id *id;
|
|
int rc;
|
|
int rc;
|
|
@@ -1146,7 +1073,7 @@ ksocknal_process_receive(struct ksock_conn *conn)
|
|
conn->ksnc_rx_state == SOCKNAL_RX_LNET_HEADER ||
|
|
conn->ksnc_rx_state == SOCKNAL_RX_LNET_HEADER ||
|
|
conn->ksnc_rx_state == SOCKNAL_RX_SLOP);
|
|
conn->ksnc_rx_state == SOCKNAL_RX_SLOP);
|
|
again:
|
|
again:
|
|
- if (conn->ksnc_rx_nob_wanted) {
|
|
|
|
|
|
+ if (iov_iter_count(&conn->ksnc_rx_to)) {
|
|
rc = ksocknal_receive(conn);
|
|
rc = ksocknal_receive(conn);
|
|
|
|
|
|
if (rc <= 0) {
|
|
if (rc <= 0) {
|
|
@@ -1171,7 +1098,7 @@ ksocknal_process_receive(struct ksock_conn *conn)
|
|
return (!rc ? -ESHUTDOWN : rc);
|
|
return (!rc ? -ESHUTDOWN : rc);
|
|
}
|
|
}
|
|
|
|
|
|
- if (conn->ksnc_rx_nob_wanted) {
|
|
|
|
|
|
+ if (iov_iter_count(&conn->ksnc_rx_to)) {
|
|
/* short read */
|
|
/* short read */
|
|
return -EAGAIN;
|
|
return -EAGAIN;
|
|
}
|
|
}
|
|
@@ -1234,16 +1161,13 @@ ksocknal_process_receive(struct ksock_conn *conn)
|
|
}
|
|
}
|
|
|
|
|
|
conn->ksnc_rx_state = SOCKNAL_RX_LNET_HEADER;
|
|
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_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 */
|
|
goto again; /* read lnet header now */
|
|
|
|
|
|
@@ -1345,26 +1269,9 @@ ksocknal_recv(struct lnet_ni *ni, void *private, struct lnet_msg *msg,
|
|
LASSERT(to->nr_segs <= LNET_MAX_IOV);
|
|
LASSERT(to->nr_segs <= LNET_MAX_IOV);
|
|
|
|
|
|
conn->ksnc_cookie = msg;
|
|
conn->ksnc_cookie = msg;
|
|
- conn->ksnc_rx_nob_wanted = iov_iter_count(to);
|
|
|
|
conn->ksnc_rx_nob_left = rlen;
|
|
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);
|
|
LASSERT(conn->ksnc_rx_scheduled);
|
|
|
|
|
|
@@ -2329,12 +2236,12 @@ ksocknal_find_timed_out_conn(struct ksock_peer *peer)
|
|
conn->ksnc_rx_deadline)) {
|
|
conn->ksnc_rx_deadline)) {
|
|
/* Timed out incomplete incoming message */
|
|
/* Timed out incomplete incoming message */
|
|
ksocknal_conn_addref(conn);
|
|
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),
|
|
libcfs_id2str(peer->ksnp_id),
|
|
&conn->ksnc_ipaddr,
|
|
&conn->ksnc_ipaddr,
|
|
conn->ksnc_port,
|
|
conn->ksnc_port,
|
|
conn->ksnc_rx_state,
|
|
conn->ksnc_rx_state,
|
|
- conn->ksnc_rx_nob_wanted,
|
|
|
|
|
|
+ iov_iter_count(&conn->ksnc_rx_to),
|
|
conn->ksnc_rx_nob_left);
|
|
conn->ksnc_rx_nob_left);
|
|
return conn;
|
|
return conn;
|
|
}
|
|
}
|