int tx_nob; /* # packet bytes */
int tx_resid; /* residual bytes */
int tx_niov; /* # packet kvec frags */
- struct kvec *tx_iov; /* packet kvec frags */
int tx_nkiov; /* # packet page frags */
unsigned short tx_zc_aborted; /* aborted ZC request */
unsigned short tx_zc_capable:1; /* payload is large enough for ZC */
extern void ksocknal_lib_push_conn(struct ksock_conn *conn);
extern int ksocknal_lib_get_conn_addrs(struct ksock_conn *conn);
extern int ksocknal_lib_setup_sock(struct socket *so);
-extern int ksocknal_lib_send_iov(struct ksock_conn *conn, struct ksock_tx *tx,
+extern int ksocknal_lib_send_hdr(struct ksock_conn *conn, struct ksock_tx *tx,
struct kvec *scratch_iov);
extern int ksocknal_lib_send_kiov(struct ksock_conn *conn, struct ksock_tx *tx,
struct kvec *scratch_iov);
tx->tx_lnetmsg = NULL;
tx->tx_kiov = NULL;
tx->tx_nkiov = 0;
- tx->tx_iov = &tx->tx_hdr;
tx->tx_niov = 1;
tx->tx_nonblk = nonblk;
}
static int
-ksocknal_send_iov(struct ksock_conn *conn, struct ksock_tx *tx,
+ksocknal_send_hdr(struct ksock_conn *conn, struct ksock_tx *tx,
struct kvec *scratch_iov)
{
- struct kvec *iov = tx->tx_iov;
+ struct kvec *iov = &tx->tx_hdr;
int nob;
int rc;
LASSERT(tx->tx_niov > 0);
- /* Never touch tx->tx_iov inside ksocknal_lib_send_iov() */
- rc = ksocknal_lib_send_iov(conn, tx, scratch_iov);
+ /* Never touch tx->tx_hdr inside ksocknal_lib_send_hdr() */
+ rc = ksocknal_lib_send_hdr(conn, tx, scratch_iov);
if (rc <= 0) /* sent nothing? */
return rc;
tx->tx_resid -= nob;
/* "consume" iov */
- do {
- LASSERT(tx->tx_niov > 0);
+ LASSERT(tx->tx_niov == 1);
- if (nob < (int) iov->iov_len) {
- iov->iov_base += nob;
- iov->iov_len -= nob;
- return rc;
- }
+ if (nob < (int) iov->iov_len) {
+ iov->iov_base += nob;
+ iov->iov_len -= nob;
+ return rc;
+ }
- nob -= iov->iov_len;
- tx->tx_iov = ++iov;
- tx->tx_niov--;
- } while (nob != 0);
+ LASSERT(nob == iov->iov_len);
+ tx->tx_niov--;
return rc;
}
ksocknal_data.ksnd_enomem_tx--;
rc = -EAGAIN;
} else if (tx->tx_niov != 0) {
- rc = ksocknal_send_iov(conn, tx, scratch_iov);
+ rc = ksocknal_send_hdr(conn, tx, scratch_iov);
} else {
rc = ksocknal_send_kiov(conn, tx, scratch_iov);
}
ksocknal_tx_prep(conn, tx);
- /* Ensure the frags we've been given EXACTLY match the number of
- * bytes we want to send. Many TCP/IP stacks disregard any total
+ /* Ensure the frags we've been given EXACTLY match the number of
+ * bytes we want to send. Many TCP/IP stacks disregard any total
* size parameters passed to them and just look at the frags.
- *
- * We always expect at least 1 mapped fragment containing the
- * complete ksocknal message header. */
- LASSERT (lnet_iov_nob (tx->tx_niov, tx->tx_iov) +
- lnet_kiov_nob(tx->tx_nkiov, tx->tx_kiov) ==
- (unsigned int)tx->tx_nob);
- LASSERT (tx->tx_niov >= 1);
- LASSERT (tx->tx_resid == tx->tx_nob);
+ *
+ * We always expect at least 1 mapped fragment containing the
+ * complete ksocknal message header.
+ */
+ LASSERT(lnet_iov_nob(tx->tx_niov, &tx->tx_hdr) +
+ lnet_kiov_nob(tx->tx_nkiov, tx->tx_kiov) ==
+ (unsigned int)tx->tx_nob);
+ LASSERT(tx->tx_niov >= 1);
+ LASSERT(tx->tx_resid == tx->tx_nob);
CDEBUG (D_NET, "Packet %p type %d, nob %d niov %d nkiov %d\n",
tx, (tx->tx_lnetmsg != NULL) ? tx->tx_lnetmsg->msg_hdr.type:
tx->tx_lnetmsg = lntmsg;
tx->tx_niov = 1;
- tx->tx_iov = &tx->tx_hdr;
tx->tx_kiov = tx->tx_payload;
tx->tx_nkiov = lnet_extract_kiov(payload_niov, tx->tx_kiov,
payload_niov, payload_kiov,
}
int
-ksocknal_lib_send_iov(struct ksock_conn *conn, struct ksock_tx *tx,
+ksocknal_lib_send_hdr(struct ksock_conn *conn, struct ksock_tx *tx,
struct kvec *scratchiov)
{
struct socket *sock = conn->ksnc_sock;
- int nob;
+ int nob = 0;
int rc;
if (*ksocknal_tunables.ksnd_enable_csum && /* checksum enabled */
unsigned int niov = tx->tx_niov;
#endif
struct msghdr msg = { .msg_flags = MSG_DONTWAIT };
- int i;
- for (nob = i = 0; i < niov; i++) {
- scratchiov[i] = tx->tx_iov[i];
- nob += scratchiov[i].iov_len;
+ if (tx->tx_niov) {
+ scratchiov[0] = tx->tx_hdr;
+ nob += scratchiov[0].iov_len;
}
if (!list_empty(&conn->ksnc_tx_queue) ||
__u32 csum;
void *base;
- LASSERT(tx->tx_iov[0].iov_base == (void *)&tx->tx_msg);
- LASSERT(tx->tx_conn != NULL);
- LASSERT(tx->tx_conn->ksnc_proto == &ksocknal_protocol_v2x);
+ LASSERT(tx->tx_hdr.iov_base == (void *)&tx->tx_msg);
+ LASSERT(tx->tx_conn != NULL);
+ LASSERT(tx->tx_conn->ksnc_proto == &ksocknal_protocol_v2x);
tx->tx_msg.ksm_csum = 0;
- csum = ksocknal_csum(~0, (void *)tx->tx_iov[0].iov_base,
- tx->tx_iov[0].iov_len);
+ csum = ksocknal_csum(~0, (void *)tx->tx_hdr.iov_base,
+ tx->tx_hdr.iov_len);
- if (tx->tx_kiov != NULL) {
- for (i = 0; i < tx->tx_nkiov; i++) {
- base = kmap(tx->tx_kiov[i].bv_page) +
- tx->tx_kiov[i].bv_offset;
+ for (i = 0; i < tx->tx_nkiov; i++) {
+ base = kmap(tx->tx_kiov[i].bv_page) +
+ tx->tx_kiov[i].bv_offset;
- csum = ksocknal_csum(csum, base, tx->tx_kiov[i].bv_len);
+ csum = ksocknal_csum(csum, base, tx->tx_kiov[i].bv_len);
- kunmap(tx->tx_kiov[i].bv_page);
- }
- } else {
- for (i = 1; i < tx->tx_niov; i++)
- csum = ksocknal_csum(csum, tx->tx_iov[i].iov_base,
- tx->tx_iov[i].iov_len);
- }
+ kunmap(tx->tx_kiov[i].bv_page);
+ }
if (*ksocknal_tunables.ksnd_inject_csum_error) {
csum++;
LASSERT(tx->tx_msg.ksm_type != KSOCK_MSG_NOOP);
LASSERT(tx->tx_lnetmsg != NULL);
- tx->tx_iov[0].iov_base = (void *)&tx->tx_lnetmsg->msg_hdr;
- tx->tx_iov[0].iov_len = sizeof(struct lnet_hdr);
+ tx->tx_hdr.iov_base = (void *)&tx->tx_lnetmsg->msg_hdr;
+ tx->tx_hdr.iov_len = sizeof(struct lnet_hdr);
tx->tx_nob = tx->tx_lnetmsg->msg_len + sizeof(struct lnet_hdr);
tx->tx_resid = tx->tx_nob;
static void
ksocknal_pack_msg_v2(struct ksock_tx *tx)
{
- tx->tx_iov[0].iov_base = (void *)&tx->tx_msg;
+ tx->tx_hdr.iov_base = (void *)&tx->tx_msg;
if (tx->tx_lnetmsg != NULL) {
LASSERT(tx->tx_msg.ksm_type != KSOCK_MSG_NOOP);
tx->tx_msg.ksm_u.lnetmsg.ksnm_hdr = tx->tx_lnetmsg->msg_hdr;
- tx->tx_iov[0].iov_len = sizeof(struct ksock_msg);
+ tx->tx_hdr.iov_len = sizeof(struct ksock_msg);
tx->tx_resid = tx->tx_nob = sizeof(struct ksock_msg) + tx->tx_lnetmsg->msg_len;
} else {
LASSERT(tx->tx_msg.ksm_type == KSOCK_MSG_NOOP);
- tx->tx_iov[0].iov_len = offsetof(struct ksock_msg, ksm_u.lnetmsg.ksnm_hdr);
+ tx->tx_hdr.iov_len = offsetof(struct ksock_msg,
+ ksm_u.lnetmsg.ksnm_hdr);
tx->tx_resid = tx->tx_nob = offsetof(struct ksock_msg, ksm_u.lnetmsg.ksnm_hdr);
}
/* Don't checksum before start sending, because packet can be piggybacked with ACK */