1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
5 * User-level wrappers that dispatch across the protection boundaries
7 * Copyright (c) 2001-2003 Cluster File Systems, Inc.
8 * Copyright (c) 2001-2002 Sandia National Laboratories
10 * This file is part of Lustre, http://www.sf.net/projects/lustre/
12 * Lustre 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 * Lustre 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 Lustre; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 # define DEBUG_SUBSYSTEM S_PORTALS
27 #include <portals/api-support.h>
29 static int do_forward(ptl_handle_any_t any_h, int cmd, void *argbuf,
30 int argsize, void *retbuf, int retsize)
35 CERROR("Not initialized\n");
39 nal = ptl_hndl2nal(&any_h);
41 return PTL_HANDLE_INVALID;
43 nal->forward(nal, cmd, argbuf, argsize, retbuf, retsize);
48 int PtlGetId(ptl_handle_ni_t ni_handle, ptl_process_id_t *id)
54 args.handle_in = ni_handle;
56 rc = do_forward(ni_handle, PTL_GETID, &args, sizeof(args), &ret,
67 int PtlFailNid (ptl_handle_ni_t interface, ptl_nid_t nid, unsigned int threshold)
73 args.interface = interface;
75 args.threshold = threshold;
77 rc = do_forward (interface, PTL_FAILNID,
78 &args, sizeof(args), &ret, sizeof (ret));
80 return ((rc != PTL_OK) ? rc : ret.rc);
83 int PtlNIStatus(ptl_handle_ni_t interface_in, ptl_sr_index_t register_in,
84 ptl_sr_value_t * status_out)
90 args.interface_in = interface_in;
91 args.register_in = register_in;
93 rc = do_forward(interface_in, PTL_NISTATUS, &args, sizeof(args), &ret,
100 *status_out = ret.status_out;
105 int PtlNIDist(ptl_handle_ni_t interface_in, ptl_process_id_t process_in,
106 unsigned long *distance_out)
112 args.interface_in = interface_in;
113 args.process_in = process_in;
115 rc = do_forward(interface_in, PTL_NIDIST, &args, sizeof(args), &ret,
122 *distance_out = ret.distance_out;
127 int PtlMEAttach(ptl_handle_ni_t interface_in, ptl_pt_index_t index_in,
128 ptl_process_id_t match_id_in, ptl_match_bits_t match_bits_in,
129 ptl_match_bits_t ignore_bits_in, ptl_unlink_t unlink_in,
130 ptl_ins_pos_t pos_in, ptl_handle_me_t * handle_out)
136 args.interface_in = interface_in;
137 args.index_in = index_in;
138 args.match_id_in = match_id_in;
139 args.match_bits_in = match_bits_in;
140 args.ignore_bits_in = ignore_bits_in;
141 args.unlink_in = unlink_in;
142 args.position_in = pos_in;
144 rc = do_forward(interface_in, PTL_MEATTACH, &args, sizeof(args), &ret,
151 handle_out->nal_idx = interface_in.nal_idx;
152 handle_out->cookie = ret.handle_out.cookie;
158 int PtlMEInsert(ptl_handle_me_t current_in, ptl_process_id_t match_id_in,
159 ptl_match_bits_t match_bits_in, ptl_match_bits_t ignore_bits_in,
160 ptl_unlink_t unlink_in, ptl_ins_pos_t position_in,
161 ptl_handle_me_t * handle_out)
167 args.current_in = current_in;
168 args.match_id_in = match_id_in;
169 args.match_bits_in = match_bits_in;
170 args.ignore_bits_in = ignore_bits_in;
171 args.unlink_in = unlink_in;
172 args.position_in = position_in;
174 rc = do_forward(current_in, PTL_MEINSERT, &args, sizeof(args), &ret,
178 return (rc == PTL_HANDLE_INVALID) ? PTL_ME_INVALID : rc;
181 handle_out->nal_idx = current_in.nal_idx;
182 handle_out->cookie = ret.handle_out.cookie;
187 int PtlMEUnlink(ptl_handle_me_t current_in)
193 args.current_in = current_in;
194 args.unlink_in = PTL_RETAIN;
196 rc = do_forward(current_in, PTL_MEUNLINK, &args, sizeof(args), &ret,
200 return (rc == PTL_HANDLE_INVALID) ? PTL_ME_INVALID : rc;
205 int PtlTblDump(ptl_handle_ni_t ni, int index_in)
211 args.index_in = index_in;
213 rc = do_forward(ni, PTL_TBLDUMP, &args, sizeof(args), &ret,
222 int PtlMEDump(ptl_handle_me_t current_in)
228 args.current_in = current_in;
230 rc = do_forward(current_in, PTL_MEDUMP, &args, sizeof(args), &ret,
234 return (rc == PTL_HANDLE_INVALID) ? PTL_ME_INVALID : rc;
239 static ptl_handle_eq_t md2eq (ptl_md_t *md)
241 if (PtlHandleIsEqual (md->eventq, PTL_EQ_NONE))
242 return (PTL_EQ_NONE);
244 return (ptl_handle2usereq (&md->eventq)->cb_eq_handle);
248 int PtlMDAttach(ptl_handle_me_t me_in, ptl_md_t md_in,
249 ptl_unlink_t unlink_in, ptl_handle_md_t * handle_out)
255 args.eq_in = md2eq(&md_in);
258 args.unlink_in = unlink_in;
260 rc = do_forward(me_in, PTL_MDATTACH,
261 &args, sizeof(args), &ret, sizeof(ret));
264 return (rc == PTL_HANDLE_INVALID) ? PTL_ME_INVALID : rc;
267 handle_out->nal_idx = me_in.nal_idx;
268 handle_out->cookie = ret.handle_out.cookie;
275 int PtlMDBind(ptl_handle_ni_t ni_in, ptl_md_t md_in,
276 ptl_unlink_t unlink_in, ptl_handle_md_t * handle_out)
282 args.eq_in = md2eq(&md_in);
285 args.unlink_in = unlink_in;
287 rc = do_forward(ni_in, PTL_MDBIND,
288 &args, sizeof(args), &ret, sizeof(ret));
294 handle_out->nal_idx = ni_in.nal_idx;
295 handle_out->cookie = ret.handle_out.cookie;
300 int PtlMDUpdate(ptl_handle_md_t md_in, ptl_md_t *old_inout,
301 ptl_md_t *new_inout, ptl_handle_eq_t testq_in)
303 PtlMDUpdate_internal_in args;
304 PtlMDUpdate_internal_out ret;
310 args.old_inout = *old_inout;
311 args.old_inout_valid = 1;
313 args.old_inout_valid = 0;
316 args.new_inout = *new_inout;
317 args.new_inout_valid = 1;
319 args.new_inout_valid = 0;
321 if (PtlHandleIsEqual (testq_in, PTL_EQ_NONE)) {
322 args.testq_in = PTL_EQ_NONE;
323 args.sequence_in = -1;
325 ptl_eq_t *eq = ptl_handle2usereq (&testq_in);
327 args.testq_in = eq->cb_eq_handle;
328 args.sequence_in = eq->sequence;
331 rc = do_forward(md_in, PTL_MDUPDATE, &args, sizeof(args), &ret,
334 return (rc == PTL_HANDLE_INVALID) ? PTL_MD_INVALID : rc;
337 *old_inout = ret.old_inout;
342 int PtlMDUnlink(ptl_handle_md_t md_in)
349 rc = do_forward(md_in, PTL_MDUNLINK, &args, sizeof(args), &ret,
352 return (rc == PTL_HANDLE_INVALID) ? PTL_MD_INVALID : rc;
357 int PtlEQAlloc(ptl_handle_ni_t interface, ptl_size_t count,
358 ptl_eq_handler_t callback,
359 ptl_handle_eq_t * handle_out)
362 ptl_event_t *ev = NULL;
371 nal = ptl_hndl2nal (&interface);
373 return PTL_HANDLE_INVALID;
375 if (count != LOWEST_BIT_SET(count)) { /* not a power of 2 already */
376 do { /* knock off all but the top bit... */
377 count &= ~LOWEST_BIT_SET (count);
378 } while (count != LOWEST_BIT_SET(count));
380 count <<= 1; /* ...and round up */
383 if (count == 0) /* catch bad parameter / overflow on roundup */
384 return (PTL_VAL_FAILED);
386 PORTAL_ALLOC(ev, count * sizeof(ptl_event_t));
390 for (i = 0; i < count; i++)
393 args.ni_in = interface;
394 args.count_in = count;
396 args.len_in = count * sizeof(*ev);
397 args.callback_in = callback;
399 rc = do_forward(interface, PTL_EQALLOC, &args, sizeof(args), &ret,
404 GOTO(fail, rc = ret.rc);
406 PORTAL_ALLOC(eq, sizeof(*eq));
416 /* EQ handles are a little wierd. PtlEQGet() just looks at the
417 * queued events in shared memory. It doesn't want to do_forward()
418 * at all, so the cookie in the EQ handle we pass out of here is
419 * simply a pointer to the event queue we just set up. We stash
420 * the handle returned by do_forward(), so we can pass it back via
421 * do_forward() when we need to. */
423 eq->cb_eq_handle.nal_idx = interface.nal_idx;
424 eq->cb_eq_handle.cookie = ret.handle_out.cookie;
426 handle_out->nal_idx = interface.nal_idx;
427 handle_out->cookie = (__u64)((unsigned long)eq);
431 PORTAL_FREE(ev, count * sizeof(ptl_event_t));
435 int PtlEQFree(ptl_handle_eq_t eventq)
442 eq = ptl_handle2usereq (&eventq);
443 args.eventq_in = eq->cb_eq_handle;
445 rc = do_forward(eq->cb_eq_handle, PTL_EQFREE, &args,
446 sizeof(args), &ret, sizeof(ret));
448 /* XXX we're betting rc == PTL_OK here */
449 PORTAL_FREE(eq->base, eq->size * sizeof(ptl_event_t));
450 PORTAL_FREE(eq, sizeof(*eq));
455 int PtlACEntry(ptl_handle_ni_t ni_in, ptl_ac_index_t index_in,
456 ptl_process_id_t match_id_in, ptl_pt_index_t portal_in)
463 * Copy arguments into the argument block to
464 * hand to the forwarding object
467 args.index_in = index_in;
468 args.match_id_in = match_id_in;
469 args.portal_in = portal_in;
471 rc = do_forward(ni_in, PTL_ACENTRY, &args, sizeof(args), &ret,
474 return (rc != PTL_OK) ? rc : ret.rc;
477 int PtlPut(ptl_handle_md_t md_in, ptl_ack_req_t ack_req_in,
478 ptl_process_id_t target_in, ptl_pt_index_t portal_in,
479 ptl_ac_index_t cookie_in, ptl_match_bits_t match_bits_in,
480 ptl_size_t offset_in, ptl_hdr_data_t hdr_data_in)
487 * Copy arguments into the argument block to
488 * hand to the forwarding object
491 args.ack_req_in = ack_req_in;
492 args.target_in = target_in;
493 args.portal_in = portal_in;
494 args.cookie_in = cookie_in;
495 args.match_bits_in = match_bits_in;
496 args.offset_in = offset_in;
497 args.hdr_data_in = hdr_data_in;
499 rc = do_forward(md_in, PTL_PUT, &args, sizeof(args), &ret, sizeof(ret));
501 return (rc != PTL_OK) ? rc : ret.rc;
504 int PtlGet(ptl_handle_md_t md_in, ptl_process_id_t target_in,
505 ptl_pt_index_t portal_in, ptl_ac_index_t cookie_in,
506 ptl_match_bits_t match_bits_in, ptl_size_t offset_in)
513 * Copy arguments into the argument block to
514 * hand to the forwarding object
517 args.target_in = target_in;
518 args.portal_in = portal_in;
519 args.cookie_in = cookie_in;
520 args.match_bits_in = match_bits_in;
521 args.offset_in = offset_in;
523 rc = do_forward(md_in, PTL_GET, &args, sizeof(args), &ret, sizeof(ret));
525 return (rc != PTL_OK) ? rc : ret.rc;