* GPL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*/
/*
enum {
SOCKLND_TIMEOUT = 1,
SOCKLND_CREDITS,
- SOCKLND_PEER_CREDITS,
+ SOCKLND_PEER_TXCREDITS,
+ SOCKLND_PEER_RTRCREDITS,
+ SOCKLND_PEER_TIMEOUT,
SOCKLND_NCONNDS,
SOCKLND_RECONNECTS_MIN,
SOCKLND_RECONNECTS_MAX,
SOCKLND_TX_BUFFER_SIZE,
SOCKLND_NAGLE,
SOCKLND_IRQ_AFFINITY,
+ SOCKLND_ROUND_ROBIN,
+ SOCKLND_KEEPALIVE,
SOCKLND_KEEPALIVE_IDLE,
SOCKLND_KEEPALIVE_COUNT,
SOCKLND_KEEPALIVE_INTVL,
#define SOCKLND_TIMEOUT CTL_UNNUMBERED
#define SOCKLND_CREDITS CTL_UNNUMBERED
-#define SOCKLND_PEER_CREDITS CTL_UNNUMBERED
+#define SOCKLND_PEER_TXCREDITS CTL_UNNUMBERED
+#define SOCKLND_PEER_RTRCREDITS CTL_UNNUMBERED
+#define SOCKLND_PEER_TIMEOUT CTL_UNNUMBERED
#define SOCKLND_NCONNDS CTL_UNNUMBERED
#define SOCKLND_RECONNECTS_MIN CTL_UNNUMBERED
#define SOCKLND_RECONNECTS_MAX CTL_UNNUMBERED
#define SOCKLND_TX_BUFFER_SIZE CTL_UNNUMBERED
#define SOCKLND_NAGLE CTL_UNNUMBERED
#define SOCKLND_IRQ_AFFINITY CTL_UNNUMBERED
+#define SOCKLND_ROUND_ROBIN CTL_UNNUMBERED
+#define SOCKLND_KEEPALIVE CTL_UNNUMBERED
#define SOCKLND_KEEPALIVE_IDLE CTL_UNNUMBERED
#define SOCKLND_KEEPALIVE_COUNT CTL_UNNUMBERED
#define SOCKLND_KEEPALIVE_INTVL CTL_UNNUMBERED
.strategy = &sysctl_intvec,
},
{
- .ctl_name = SOCKLND_PEER_CREDITS,
+ .ctl_name = SOCKLND_PEER_TXCREDITS,
.procname = "peer_credits",
- .data = &ksocknal_tunables.ksnd_peercredits,
+ .data = &ksocknal_tunables.ksnd_peertxcredits,
.maxlen = sizeof (int),
.mode = 0444,
.proc_handler = &proc_dointvec,
.strategy = &sysctl_intvec,
},
+ {
+ .ctl_name = SOCKLND_PEER_RTRCREDITS,
+ .procname = "peer_buffer_credits",
+ .data = &ksocknal_tunables.ksnd_peerrtrcredits,
+ .maxlen = sizeof (int),
+ .mode = 0444,
+ .proc_handler = &proc_dointvec,
+ .strategy = &sysctl_intvec,
+ },
+ {
+ .ctl_name = SOCKLND_PEER_TIMEOUT,
+ .procname = "peer_timeout",
+ .data = &ksocknal_tunables.ksnd_peertimeout,
+ .maxlen = sizeof (int),
+ .mode = 0444,
+ .proc_handler = &proc_dointvec
+ .strategy = &sysctl_intvec,
+ },
{
.ctl_name = SOCKLND_NCONNDS,
.procname = "nconnds",
{
.ctl_name = SOCKLND_ZERO_COPY,
.procname = "zero_copy",
- .data = &ksocknal_tunables.ksnd_zc_min_frag,
+ .data = &ksocknal_tunables.ksnd_zc_min_payload,
.maxlen = sizeof (int),
.mode = 0644,
.proc_handler = &proc_dointvec,
},
#endif
{
+ .ctl_name = SOCKLND_ROUND_ROBIN,
+ .procname = "round_robin",
+ .data = &ksocknal_tunables.ksnd_round_robin,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec,
+ .strategy = &sysctl_intvec,
+ },
+ {
+ .ctl_name = SOCKLND_KEEPALIVE,
+ .procname = "keepalive",
+ .data = &ksocknal_tunables.ksnd_keepalive,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec,
+ .strategy = &sysctl_intvec,
+ },
+ {
.ctl_name = SOCKLND_KEEPALIVE_IDLE,
.procname = "keepalive_idle",
.data = &ksocknal_tunables.ksnd_keepalive_idle,
int
ksocknal_lib_tunables_init ()
{
+ if (!*ksocknal_tunables.ksnd_typed_conns) {
+ int rc = -EINVAL;
+#if SOCKNAL_VERSION_DEBUG
+ if (*ksocknal_tunables.ksnd_protocol < 3)
+ rc = 0;
+#endif
+ if (rc != 0) {
+ CERROR("Protocol V3.x MUST have typed connections\n");
+ return rc;
+ }
+ }
+
if (*ksocknal_tunables.ksnd_zc_recv_min_nfrags < 2)
*ksocknal_tunables.ksnd_zc_recv_min_nfrags = 2;
if (*ksocknal_tunables.ksnd_zc_recv_min_nfrags > LNET_MAX_IOV)
}
int
-ksocknal_lib_zc_capable(struct socket *sock)
+ksocknal_lib_zc_capable(ksock_conn_t *conn)
{
- int caps = sock->sk->sk_route_caps;
+ int caps = conn->ksnc_sock->sk->sk_route_caps;
+
+ if (conn->ksnc_proto == &ksocknal_protocol_v1x)
+ return 0;
/* ZC if the socket supports scatter/gather and doesn't need software
* checksums */
nob += scratchiov[i].iov_len;
}
- if (!list_empty(&conn->ksnc_tx_queue) ||
+ if (!cfs_list_empty(&conn->ksnc_tx_queue) ||
nob < tx->tx_resid)
msg.msg_flags |= MSG_MORE;
ksocknal_lib_send_kiov (ksock_conn_t *conn, ksock_tx_t *tx)
{
struct socket *sock = conn->ksnc_sock;
- lnet_kiov_t *kiov = tx->tx_kiov;
+ lnet_kiov_t *kiov = tx->tx_kiov;
int rc;
int nob;
+ /* Not NOOP message */
+ LASSERT (tx->tx_lnetmsg != NULL);
+
/* NB we can't trust socket ops to either consume our iovs
* or leave them alone. */
-
- if (kiov->kiov_len >= *ksocknal_tunables.ksnd_zc_min_frag &&
- tx->tx_msg.ksm_zc_req_cookie != 0) {
+ if (tx->tx_msg.ksm_zc_cookies[0] != 0) {
/* Zero copy is enabled */
struct sock *sk = sock->sk;
struct page *page = kiov->kiov_page;
CDEBUG(D_NET, "page %p + offset %x for %d\n",
page, offset, kiov->kiov_len);
- if (!list_empty(&conn->ksnc_tx_queue) ||
+ if (!cfs_list_empty(&conn->ksnc_tx_queue) ||
fragsize < tx->tx_resid)
msgflg |= MSG_MORE;
nob += scratchiov[i].iov_len = kiov[i].kiov_len;
}
- if (!list_empty(&conn->ksnc_tx_queue) ||
+ if (!cfs_list_empty(&conn->ksnc_tx_queue) ||
nob < tx->tx_resid)
msg.msg_flags |= MSG_MORE;
" ready" : " blocked"),
(conn == NULL) ? "" : (conn->ksnc_tx_scheduled ?
" scheduled" : " idle"),
- (conn == NULL) ? "" : (list_empty (&conn->ksnc_tx_queue) ?
+ (conn == NULL) ? "" : (cfs_list_empty (&conn->ksnc_tx_queue) ?
" empty" : " queued"));
if (conn == NULL) { /* raced with ksocknal_terminate_conn */
sched = conn->ksnc_scheduler;
cfs_spin_lock_bh (&sched->kss_lock);
-
+
if (!SOCK_TEST_NOSPACE(conn->ksnc_sock) &&
!conn->ksnc_tx_ready) {
/* SOCK_NOSPACE is set when the socket fills
* after a timeout */
rc = -ENOMEM;
}
-
+
cfs_spin_unlock_bh (&sched->kss_lock);
return rc;
}
-__u64
-ksocknal_lib_new_incarnation(void)
-{
- struct timeval tv;
-
- /* The incarnation number is the time this module loaded and it
- * identifies this particular instance of the socknal. Hopefully
- * we won't be able to reboot more frequently than 1MHz for the
- * forseeable future :) */
-
- do_gettimeofday(&tv);
-
- return (((__u64)tv.tv_sec) * 1000000) + tv.tv_usec;
-}
-
int
ksocknal_lib_bind_thread_to_cpu(int id)
{