int ksnd_nschedulers; /* # schedulers */
ksock_sched_t *ksnd_schedulers; /* their state */
- atomic_t ksnd_nactive_ltxs; /* #active ltxs */
+ atomic_t ksnd_nactive_txs; /* #active txs */
struct list_head ksnd_deathrow_conns; /* conns to close: reaper_lock*/
struct list_head ksnd_zombie_conns; /* conns to free: reaper_lock */
int tx_nkiov; /* # packet page frags */
lnet_kiov_t *tx_kiov; /* packet page frags */
struct ksock_conn *tx_conn; /* owning conn */
- lnet_hdr_t *tx_hdr; /* packet header (for debug only) */
+ lnet_msg_t *tx_lnetmsg; /* lnet message for lnet_finalize() */
#if SOCKNAL_ZC
zccd_t tx_zccd; /* zero copy callback descriptor */
#endif
+ int tx_desc_size; /* size of this descriptor */
+ union {
+ struct {
+ struct iovec iov; /* virt hdr */
+ lnet_kiov_t kiov[0]; /* paged payload */
+ } paged;
+ struct {
+ struct iovec iov[1]; /* virt hdr + payload */
+ } virt;
+ } tx_frags;
} ksock_tx_t;
#define KSOCK_ZCCD_2_TX(ptr) list_entry (ptr, ksock_tx_t, tx_zccd)
/* network zero copy callback descriptor embedded in ksock_tx_t */
-typedef struct /* locally transmitted packet */
-{
- ksock_tx_t ltx_tx; /* send info */
- void *ltx_private; /* lnet_finalize() callback arg */
- void *ltx_cookie; /* lnet_finalize() callback arg */
- lnet_hdr_t ltx_hdr; /* buffer for packet header */
- int ltx_desc_size; /* bytes allocated for this desc */
- struct iovec ltx_iov[1]; /* iov for hdr + payload */
- lnet_kiov_t ltx_kiov[0]; /* kiov for payload */
-} ksock_ltx_t;
-
-#define KSOCK_TX_2_KSOCK_LTX(ptr) list_entry (ptr, ksock_ltx_t, ltx_tx)
-/* local packets (lib->socknal) embedded in ksock_ltx_t::ltx_tx */
-
-/* NB list_entry() is used here as convenient macro for calculating a
- * pointer to a struct from the address of a member. */
-
/* space for the rx frag descriptors; we either read a single contiguous
* header, or up to PTL_MD_MAX_IOV frags of payload of either type. */
typedef union {
- struct iovec iov[PTL_MD_MAX_IOV];
+ struct iovec iov[PTL_MD_MAX_IOV];
lnet_kiov_t kiov[PTL_MD_MAX_IOV];
} ksock_rxiovspace_t;
#include "socklnd.h"
void
-ksocknal_free_ltx (ksock_ltx_t *ltx)
+ksocknal_free_tx (ksock_tx_t *tx)
{
- atomic_dec(&ksocknal_data.ksnd_nactive_ltxs);
- LIBCFS_FREE(ltx, ltx->ltx_desc_size);
+ atomic_dec(&ksocknal_data.ksnd_nactive_txs);
+ LIBCFS_FREE(tx, tx->tx_desc_size);
}
int
void
ksocknal_tx_done (ksock_peer_t *peer, ksock_tx_t *tx, int asynch)
{
- ksock_ltx_t *ltx;
ENTRY;
if (tx->tx_conn != NULL) {
#endif
}
- ltx = KSOCK_TX_2_KSOCK_LTX (tx);
-
- lnet_finalize (peer->ksnp_ni, ltx->ltx_cookie,
+ lnet_finalize (peer->ksnp_ni, tx->tx_lnetmsg,
(tx->tx_resid == 0) ? 0 : -EIO);
- ksocknal_free_ltx (ltx);
+ ksocknal_free_tx (tx);
EXIT;
}
lnet_kiov_nob (tx->tx_nkiov, tx->tx_kiov) == tx->tx_nob);
LASSERT (tx->tx_niov >= 1);
LASSERT (tx->tx_iov[0].iov_len >= sizeof (lnet_hdr_t));
+ LASSERT (tx->tx_conn == NULL);
+ LASSERT (tx->tx_resid == tx->tx_nob);
CDEBUG (D_NET, "packet %p type %d, nob %d niov %d nkiov %d\n",
tx, ((lnet_hdr_t *)tx->tx_iov[0].iov_base)->type,
tx->tx_nob, tx->tx_niov, tx->tx_nkiov);
- tx->tx_conn = NULL; /* only set when assigned a conn */
- tx->tx_resid = tx->tx_nob;
- tx->tx_hdr = (lnet_hdr_t *)tx->tx_iov[0].iov_base;
-
g_lock = &ksocknal_data.ksnd_global_lock;
for (retry = 0;; retry = 1) {
lnet_kiov_t *payload_kiov = lntmsg->msg_kiov;
unsigned int payload_offset = lntmsg->msg_offset;
unsigned int payload_nob = lntmsg->msg_len;
- ksock_ltx_t *ltx;
+ ksock_tx_t *tx;
int desc_size;
int rc;
LASSERT (payload_nob == 0 || payload_niov > 0);
LASSERT (payload_niov <= PTL_MD_MAX_IOV);
-
- /* It must be OK to kmap() if required */
- LASSERT (payload_kiov == NULL || !in_interrupt ());
/* payload is either all vaddrs or all pages */
LASSERT (!(payload_kiov != NULL && payload_iov != NULL));
+ LASSERT (!in_interrupt ());
if (payload_iov != NULL)
- desc_size = offsetof(ksock_ltx_t, ltx_iov[1 + payload_niov]);
+ desc_size = offsetof(ksock_tx_t,
+ tx_frags.virt.iov[1 + payload_niov]);
else
- desc_size = offsetof(ksock_ltx_t, ltx_kiov[payload_niov]);
+ desc_size = offsetof(ksock_tx_t,
+ tx_frags.paged.kiov[payload_niov]);
- if (in_interrupt() ||
- type == LNET_MSG_ACK ||
- type == LNET_MSG_REPLY) {
- /* Can't block if in interrupt or responding to an incoming
- * message */
- LIBCFS_ALLOC_ATOMIC(ltx, desc_size);
- } else {
- LIBCFS_ALLOC(ltx, desc_size);
- }
-
- if (ltx == NULL) {
- CERROR("Can't allocate tx desc type %d size %d %s\n",
- type, desc_size, in_interrupt() ? "(intr)" : "");
+ LIBCFS_ALLOC(tx, desc_size);
+ if (tx == NULL) {
+ CERROR("Can't allocate tx desc type %d size %d\n",
+ type, desc_size);
return (-ENOMEM);
}
- atomic_inc(&ksocknal_data.ksnd_nactive_ltxs);
-
- ltx->ltx_desc_size = desc_size;
-
- /* We always have 1 mapped frag for the header */
- ltx->ltx_tx.tx_iov = ltx->ltx_iov;
- ltx->ltx_iov[0].iov_base = <x->ltx_hdr;
- ltx->ltx_iov[0].iov_len = sizeof(*hdr);
- ltx->ltx_hdr = *hdr;
+ atomic_inc(&ksocknal_data.ksnd_nactive_txs);
- ltx->ltx_private = private;
- ltx->ltx_cookie = lntmsg;
-
- ltx->ltx_tx.tx_nob = sizeof (*hdr) + payload_nob;
+ tx->tx_conn = NULL; /* set when assigned a conn */
+ tx->tx_desc_size = desc_size;
+ tx->tx_lnetmsg = lntmsg;
if (payload_iov != NULL) {
- /* payload is all mapped */
- ltx->ltx_tx.tx_kiov = NULL;
- ltx->ltx_tx.tx_nkiov = 0;
-
- ltx->ltx_tx.tx_niov =
- 1 + lnet_extract_iov(payload_niov, <x->ltx_iov[1],
- payload_niov, payload_iov,
- payload_offset, payload_nob);
+ tx->tx_kiov = NULL;
+ tx->tx_nkiov = 0;
+ tx->tx_iov = tx->tx_frags.virt.iov;
+ tx->tx_niov = 1 +
+ lnet_extract_iov(payload_niov, &tx->tx_iov[1],
+ payload_niov, payload_iov,
+ payload_offset, payload_nob);
} else {
- /* payload is all pages */
- ltx->ltx_tx.tx_niov = 1;
-
- ltx->ltx_tx.tx_kiov = ltx->ltx_kiov;
- ltx->ltx_tx.tx_nkiov =
- lnet_extract_kiov(payload_niov, ltx->ltx_kiov,
- payload_niov, payload_kiov,
- payload_offset, payload_nob);
+ tx->tx_niov = 1;
+ tx->tx_iov = &tx->tx_frags.paged.iov;
+ tx->tx_kiov = tx->tx_frags.paged.kiov;
+ tx->tx_nkiov = lnet_extract_kiov(payload_niov, tx->tx_kiov,
+ payload_niov, payload_kiov,
+ payload_offset, payload_nob);
}
- rc = ksocknal_launch_packet(ni, <x->ltx_tx, target);
+ /* first frag is the header */
+ tx->tx_iov[0].iov_base = (void *)hdr;
+ tx->tx_iov[0].iov_len = sizeof(*hdr);
+ tx->tx_resid = tx->tx_nob = sizeof (*hdr) + payload_nob;
+
+ rc = ksocknal_launch_packet(ni, tx, target);
if (rc == 0)
return (0);
- ksocknal_free_ltx(ltx);
+ ksocknal_free_tx(tx);
return (-EIO);
}
tx = list_entry (zombies.next, ksock_tx_t, tx_list);
CERROR ("Deleting packet type %d len %d %s->%s\n",
- le32_to_cpu (tx->tx_hdr->type),
- le32_to_cpu (tx->tx_hdr->payload_length),
- libcfs_nid2str(le64_to_cpu(tx->tx_hdr->src_nid)),
- libcfs_nid2str(le64_to_cpu (tx->tx_hdr->dest_nid)));
+ le32_to_cpu (tx->tx_lnetmsg->msg_hdr.type),
+ le32_to_cpu (tx->tx_lnetmsg->msg_hdr.payload_length),
+ libcfs_nid2str(le64_to_cpu(tx->tx_lnetmsg->msg_hdr.src_nid)),
+ libcfs_nid2str(le64_to_cpu (tx->tx_lnetmsg->msg_hdr.dest_nid)));
list_del (&tx->tx_list);
/* complete now */