1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (C) 2002 Cluster File Systems, Inc.
5 * Author: Eric Barton <eric@bartonsoftware.com>
7 * Copyright (C) 2002, Lawrence Livermore National Labs (LLNL)
8 * W. Marcus Miller - Based on ksocknal
10 * This file is part of Portals, http://www.sf.net/projects/sandiaportals/
12 * Portals is free software; you can redistribute it and/or
13 * modify it under the terms of version 2 of the GNU General Public
14 * License as published by the Free Software Foundation.
16 * Portals is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with Portals; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
30 * LIB functions follow
34 klonal_dist(lib_nal_t *nal, ptl_nid_t nid, unsigned long *dist)
36 *dist = 0; /* it's me */
41 klonal_send (lib_nal_t *nal,
48 unsigned int payload_niov,
49 struct iovec *payload_iov,
50 size_t payload_offset,
54 .klod_type = KLOD_IOV,
55 .klod_niov = payload_niov,
56 .klod_offset = payload_offset,
57 .klod_nob = payload_nob,
58 .klod_iov.iov = payload_iov};
61 LASSERT(nid == klonal_lib.libnal_ni.ni_pid.nid);
63 rc = lib_parse(&klonal_lib, hdr, &klod);
65 lib_finalize(&klonal_lib, private, libmsg, PTL_OK);
71 klonal_send_pages (lib_nal_t *nal,
78 unsigned int payload_niov,
79 ptl_kiov_t *payload_kiov,
80 size_t payload_offset,
84 .klod_type = KLOD_KIOV,
85 .klod_niov = payload_niov,
86 .klod_offset = payload_offset,
87 .klod_nob = payload_nob,
88 .klod_iov.kiov = payload_kiov};
91 LASSERT(nid == klonal_lib.libnal_ni.ni_pid.nid);
93 rc = lib_parse(&klonal_lib, hdr, &klod);
95 lib_finalize(&klonal_lib, private, libmsg, PTL_OK);
101 klonal_recv(lib_nal_t *nal,
110 klo_desc_t *klod = (klo_desc_t *)private;
112 /* I only handle mapped->mapped matches */
113 LASSERT(klod->klod_type == KLOD_IOV);
118 while (offset >= iov->iov_len) {
119 offset -= iov->iov_len;
125 while (klod->klod_offset >= klod->klod_iov.iov->iov_len) {
126 klod->klod_offset -= klod->klod_iov.iov->iov_len;
127 klod->klod_iov.iov++;
129 LASSERT(klod->klod_niov > 0);
133 int fraglen = MIN(iov->iov_len - offset,
134 klod->klod_iov.iov->iov_len - klod->klod_offset);
137 LASSERT(klod->klod_niov > 0);
142 memcpy((void *)((unsigned long)iov->iov_base + offset),
143 (void *)((unsigned long)klod->klod_iov.iov->iov_base +
147 if (offset + fraglen < iov->iov_len) {
155 if (klod->klod_offset + fraglen < klod->klod_iov.iov->iov_len ) {
156 klod->klod_offset += fraglen;
158 klod->klod_offset = 0;
159 klod->klod_iov.iov++;
166 lib_finalize(&klonal_lib, private, libmsg, PTL_OK);
171 klonal_recv_pages(lib_nal_t *nal,
180 void *srcaddr = NULL;
181 void *dstaddr = NULL;
182 unsigned long srcfrag = 0;
183 unsigned long dstfrag = 0;
184 unsigned long fraglen;
185 klo_desc_t *klod = (klo_desc_t *)private;
187 /* I only handle unmapped->unmapped matches */
188 LASSERT(klod->klod_type == KLOD_KIOV);
193 while (offset >= kiov->kiov_len) {
194 offset -= kiov->kiov_len;
200 while (klod->klod_offset >= klod->klod_iov.kiov->kiov_len) {
201 klod->klod_offset -= klod->klod_iov.kiov->kiov_len;
202 klod->klod_iov.kiov++;
204 LASSERT(klod->klod_niov > 0);
208 /* CAVEAT EMPTOR: I kmap 2 pages at once == slight risk of deadlock */
210 if (dstaddr == NULL) {
211 dstaddr = (void *)((unsigned long)kmap(kiov->kiov_page) +
212 kiov->kiov_offset + offset);
213 dstfrag = kiov->kiov_len - offset;
216 LASSERT(klod->klod_niov > 0);
217 if (srcaddr == NULL) {
218 srcaddr = (void *)((unsigned long)kmap(klod->klod_iov.kiov->kiov_page) +
219 klod->klod_iov.kiov->kiov_offset + klod->klod_offset);
220 srcfrag = klod->klod_iov.kiov->kiov_len - klod->klod_offset;
223 fraglen = MIN(srcfrag, dstfrag);
227 memcpy(dstaddr, srcaddr, fraglen);
229 if (fraglen < dstfrag) {
231 dstaddr = (void *)((unsigned long)dstaddr + fraglen);
233 kunmap(kiov->kiov_page);
240 if (fraglen < srcfrag) {
242 srcaddr = (void *)((unsigned long)srcaddr + fraglen);
244 kunmap(klod->klod_iov.kiov->kiov_page);
246 klod->klod_offset = 0;
247 klod->klod_iov.kiov++;
255 kunmap(kiov->kiov_page);
258 kunmap(klod->klod_iov.kiov->kiov_page);
260 lib_finalize(&klonal_lib, private, libmsg, PTL_OK);
264 lib_nal_t klonal_lib =
266 libnal_data: &klonal_data, /* NAL private data */
267 libnal_send: klonal_send,
268 libnal_send_pages: klonal_send_pages,
269 libnal_recv: klonal_recv,
270 libnal_recv_pages: klonal_recv_pages,
271 libnal_dist: klonal_dist