1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 only,
10 * as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License version 2 for more details (a copy is included
16 * in the LICENSE file that accompanied this code).
18 * You should have received a copy of the GNU General Public License
19 * version 2 along with this program; If not, see
20 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
22 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23 * CA 95054 USA or visit www.sun.com if you need additional information or
29 * Copyright 2008 Sun Microsystems, Inc. All rights reserved
30 * Use is subject to license terms.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
36 * lnet/ulnds/socklnd/usocklnd_cb.c
38 * Author: Maxim Patlasov <maxim@clusterfs.com>
44 usocklnd_send_tx_immediately(usock_conn_t *conn, usock_tx_t *tx)
49 usock_peer_t *peer = conn->uc_peer;
51 LASSERT (peer != NULL);
53 /* usocklnd_enqueue_tx() turned it on for us */
54 LASSERT(conn->uc_sending);
56 //counter_imm_start++;
57 rc = usocklnd_send_tx(conn, tx);
58 if (rc == 0) { /* partial send or connection closed */
59 pthread_mutex_lock(&conn->uc_lock);
60 list_add(&tx->tx_list, &conn->uc_tx_list);
62 pthread_mutex_unlock(&conn->uc_lock);
65 usocklnd_destroy_tx(peer->up_ni, tx);
66 /* NB: lnetmsg was finalized, so we *must* return 0 */
68 if (rc < 0) { /* real error */
69 usocklnd_conn_kill(conn);
73 /* rc == 1: tx was sent completely */
74 rc = 0; /* let's say to caller 'Ok' */
75 //counter_imm_complete++;
78 pthread_mutex_lock(&conn->uc_lock);
81 /* schedule write handler */
83 (conn->uc_state == UC_READY &&
84 (!list_empty(&conn->uc_tx_list) ||
85 !list_empty(&conn->uc_zcack_list)))) {
86 conn->uc_tx_deadline =
87 cfs_time_shift(usock_tuns.ut_timeout);
89 rc2 = usocklnd_add_pollrequest(conn, POLL_TX_SET_REQUEST, POLLOUT);
91 usocklnd_conn_kill_locked(conn);
93 usocklnd_wakeup_pollthread(conn->uc_pt_idx);
96 pthread_mutex_unlock(&conn->uc_lock);
102 usocklnd_send(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg)
105 lnet_process_id_t target = lntmsg->msg_target;
110 int send_immediately;
112 tx = usocklnd_create_tx(lntmsg);
116 rc = usocklnd_find_or_create_peer(ni, target, &peer);
118 LIBCFS_FREE (tx, tx->tx_size);
121 /* peer cannot disappear now because its refcount was incremented */
123 type = usocklnd_get_conn_type(lntmsg);
124 rc = usocklnd_find_or_create_conn(peer, type, &conn, tx, NULL,
127 usocklnd_peer_decref(peer);
128 usocklnd_check_peer_stale(ni, target);
129 LIBCFS_FREE (tx, tx->tx_size);
132 /* conn cannot disappear now because its refcount was incremented */
134 if (send_immediately)
135 rc = usocklnd_send_tx_immediately(conn, tx);
137 usocklnd_conn_decref(conn);
138 usocklnd_peer_decref(peer);
143 usocklnd_recv(lnet_ni_t *ni, void *private, lnet_msg_t *msg, int delayed,
144 unsigned int niov, struct iovec *iov, lnet_kiov_t *kiov,
145 unsigned int offset, unsigned int mlen, unsigned int rlen)
148 usock_conn_t *conn = (usock_conn_t *)private;
150 /* I don't think that we'll win much concurrency moving lock()
151 * call below lnet_extract_iov() */
152 pthread_mutex_lock(&conn->uc_lock);
154 conn->uc_rx_lnetmsg = msg;
155 conn->uc_rx_nob_wanted = mlen;
156 conn->uc_rx_nob_left = rlen;
157 conn->uc_rx_iov = conn->uc_rx_iova;
159 lnet_extract_iov(LNET_MAX_IOV, conn->uc_rx_iov,
160 niov, iov, offset, mlen);
162 /* the gap between lnet_parse() and usocklnd_recv() happened? */
163 if (conn->uc_rx_state == UC_RX_PARSE_WAIT) {
164 conn->uc_rx_flag = 1; /* waiting for incoming lnet payload */
165 conn->uc_rx_deadline =
166 cfs_time_shift(usock_tuns.ut_timeout);
167 rc = usocklnd_add_pollrequest(conn, POLL_RX_SET_REQUEST, POLLIN);
169 usocklnd_conn_kill_locked(conn);
172 usocklnd_wakeup_pollthread(conn->uc_pt_idx);
175 conn->uc_rx_state = UC_RX_LNET_PAYLOAD;
177 pthread_mutex_unlock(&conn->uc_lock);
178 usocklnd_conn_decref(conn);
183 usocklnd_accept(lnet_ni_t *ni, int sock_fd)
188 rc = usocklnd_create_passive_conn(ni, sock_fd, &conn);
191 LASSERT(conn != NULL);
193 /* disable shutdown event temporarily */
196 rc = usocklnd_add_pollrequest(conn, POLL_ADD_REQUEST, POLLIN);
198 usocklnd_wakeup_pollthread(conn->uc_pt_idx);
200 /* NB: conn reference counter was incremented while adding
201 * poll request if rc == 0 */
203 usocklnd_conn_decref(conn); /* should destroy conn if rc != 0 */