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 fprintf(stderr, "PtlGetId: Not initialized\n");
39 nal = ptl_hndl2nal(&any_h);
41 return PTL_INV_HANDLE;
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;
129 unsigned int PtlNIDebug(ptl_handle_ni_t ni, unsigned int mask_in)
135 args.mask_in = mask_in;
137 rc = do_forward(ni, PTL_NIDEBUG, &args, sizeof(args), &ret,
146 int PtlMEAttach(ptl_handle_ni_t interface_in, ptl_pt_index_t index_in,
147 ptl_process_id_t match_id_in, ptl_match_bits_t match_bits_in,
148 ptl_match_bits_t ignore_bits_in, ptl_unlink_t unlink_in,
149 ptl_ins_pos_t pos_in, ptl_handle_me_t * handle_out)
155 args.interface_in = interface_in;
156 args.index_in = index_in;
157 args.match_id_in = match_id_in;
158 args.match_bits_in = match_bits_in;
159 args.ignore_bits_in = ignore_bits_in;
160 args.unlink_in = unlink_in;
161 args.position_in = pos_in;
163 rc = do_forward(interface_in, PTL_MEATTACH, &args, sizeof(args), &ret,
170 handle_out->nal_idx = interface_in.nal_idx;
171 handle_out->cookie = ret.handle_out.cookie;
177 int PtlMEInsert(ptl_handle_me_t current_in, ptl_process_id_t match_id_in,
178 ptl_match_bits_t match_bits_in, ptl_match_bits_t ignore_bits_in,
179 ptl_unlink_t unlink_in, ptl_ins_pos_t position_in,
180 ptl_handle_me_t * handle_out)
186 args.current_in = current_in;
187 args.match_id_in = match_id_in;
188 args.match_bits_in = match_bits_in;
189 args.ignore_bits_in = ignore_bits_in;
190 args.unlink_in = unlink_in;
191 args.position_in = position_in;
193 rc = do_forward(current_in, PTL_MEINSERT, &args, sizeof(args), &ret,
197 return (rc == PTL_INV_HANDLE) ? PTL_INV_ME : rc;
200 handle_out->nal_idx = current_in.nal_idx;
201 handle_out->cookie = ret.handle_out.cookie;
206 int PtlMEUnlink(ptl_handle_me_t current_in)
212 args.current_in = current_in;
213 args.unlink_in = PTL_RETAIN;
215 rc = do_forward(current_in, PTL_MEUNLINK, &args, sizeof(args), &ret,
219 return (rc == PTL_INV_HANDLE) ? PTL_INV_ME : rc;
224 int PtlTblDump(ptl_handle_ni_t ni, int index_in)
230 args.index_in = index_in;
232 rc = do_forward(ni, PTL_TBLDUMP, &args, sizeof(args), &ret,
241 int PtlMEDump(ptl_handle_me_t current_in)
247 args.current_in = current_in;
249 rc = do_forward(current_in, PTL_MEDUMP, &args, sizeof(args), &ret,
253 return (rc == PTL_INV_HANDLE) ? PTL_INV_ME : rc;
258 static int validate_md(ptl_handle_any_t current_in, ptl_md_t md_in)
265 fprintf(stderr, "PtlMDAttach/Bind/Update: Not initialized\n");
269 nal = ptl_hndl2nal(¤t_in);
271 return PTL_INV_HANDLE;
273 if (nal->validate != NULL) /* nal->validate not a NOOP */
275 if ((md_in.options & PTL_MD_IOV) == 0) /* contiguous */
277 rc = nal->validate (nal, md_in.start, md_in.length);
283 struct iovec *iov = (struct iovec *)md_in.start;
285 for (i = 0; i < md_in.niov; i++, iov++)
287 rc = nal->validate (nal, iov->iov_base, iov->iov_len);
297 static ptl_handle_eq_t md2eq (ptl_md_t *md)
299 if (PtlHandleEqual (md->eventq, PTL_EQ_NONE))
300 return (PTL_EQ_NONE);
302 return (ptl_handle2usereq (&md->eventq)->cb_eq_handle);
306 int PtlMDAttach(ptl_handle_me_t me_in, ptl_md_t md_in,
307 ptl_unlink_t unlink_in, ptl_handle_md_t * handle_out)
313 rc = validate_md(me_in, md_in);
315 args.eq_in = md2eq(&md_in);
318 args.unlink_in = unlink_in;
320 rc = do_forward(me_in, PTL_MDATTACH,
321 &args, sizeof(args), &ret, sizeof(ret));
325 return (rc == PTL_INV_HANDLE) ? PTL_INV_ME : rc;
328 handle_out->nal_idx = me_in.nal_idx;
329 handle_out->cookie = ret.handle_out.cookie;
336 int PtlMDBind(ptl_handle_ni_t ni_in, ptl_md_t md_in,
337 ptl_handle_md_t * handle_out)
343 rc = validate_md(ni_in, md_in);
347 args.eq_in = md2eq(&md_in);
351 rc = do_forward(ni_in, PTL_MDBIND,
352 &args, sizeof(args), &ret, sizeof(ret));
358 handle_out->nal_idx = ni_in.nal_idx;
359 handle_out->cookie = ret.handle_out.cookie;
364 int PtlMDUpdate(ptl_handle_md_t md_in, ptl_md_t *old_inout,
365 ptl_md_t *new_inout, ptl_handle_eq_t testq_in)
367 PtlMDUpdate_internal_in args;
368 PtlMDUpdate_internal_out ret;
374 args.old_inout = *old_inout;
375 args.old_inout_valid = 1;
377 args.old_inout_valid = 0;
380 rc = validate_md (md_in, *new_inout);
382 return (rc == PTL_INV_HANDLE) ? PTL_INV_MD : rc;
383 args.new_inout = *new_inout;
384 args.new_inout_valid = 1;
386 args.new_inout_valid = 0;
388 if (PtlHandleEqual (testq_in, PTL_EQ_NONE)) {
389 args.testq_in = PTL_EQ_NONE;
390 args.sequence_in = -1;
392 ptl_eq_t *eq = ptl_handle2usereq (&testq_in);
394 args.testq_in = eq->cb_eq_handle;
395 args.sequence_in = eq->sequence;
398 rc = do_forward(md_in, PTL_MDUPDATE, &args, sizeof(args), &ret,
401 return (rc == PTL_INV_HANDLE) ? PTL_INV_MD : rc;
404 *old_inout = ret.old_inout;
409 int PtlMDUnlink(ptl_handle_md_t md_in)
416 rc = do_forward(md_in, PTL_MDUNLINK, &args, sizeof(args), &ret,
419 return (rc == PTL_INV_HANDLE) ? PTL_INV_MD : rc;
424 int PtlEQAlloc(ptl_handle_ni_t interface, ptl_size_t count,
425 int (*callback) (ptl_event_t * event),
426 ptl_handle_eq_t * handle_out)
429 ptl_event_t *ev = NULL;
438 nal = ptl_hndl2nal (&interface);
440 return PTL_INV_HANDLE;
442 if (count != LOWEST_BIT_SET(count)) { /* not a power of 2 already */
443 do { /* knock off all but the top bit... */
444 count &= ~LOWEST_BIT_SET (count);
445 } while (count != LOWEST_BIT_SET(count));
447 count <<= 1; /* ...and round up */
450 if (count == 0) /* catch bad parameter / overflow on roundup */
451 return (PTL_VAL_FAILED);
453 PORTAL_ALLOC(ev, count * sizeof(ptl_event_t));
457 for (i = 0; i < count; i++)
460 if (nal->validate != NULL) {
461 rc = nal->validate(nal, ev, count * sizeof(ptl_event_t));
466 args.ni_in = interface;
467 args.count_in = count;
469 args.len_in = count * sizeof(*ev);
470 args.callback_in = callback;
472 rc = do_forward(interface, PTL_EQALLOC, &args, sizeof(args), &ret,
477 GOTO(fail, rc = ret.rc);
479 PORTAL_ALLOC(eq, sizeof(*eq));
489 /* EQ handles are a little wierd. PtlEQGet() just looks at the
490 * queued events in shared memory. It doesn't want to do_forward()
491 * at all, so the cookie in the EQ handle we pass out of here is
492 * simply a pointer to the event queue we just set up. We stash
493 * the handle returned by do_forward(), so we can pass it back via
494 * do_forward() when we need to. */
496 eq->cb_eq_handle.nal_idx = interface.nal_idx;
497 eq->cb_eq_handle.cookie = ret.handle_out.cookie;
499 handle_out->nal_idx = interface.nal_idx;
500 handle_out->cookie = (__u64)((unsigned long)eq);
504 PORTAL_FREE(ev, count * sizeof(ptl_event_t));
508 int PtlEQFree(ptl_handle_eq_t eventq)
515 eq = ptl_handle2usereq (&eventq);
516 args.eventq_in = eq->cb_eq_handle;
518 rc = do_forward(eq->cb_eq_handle, PTL_EQFREE, &args,
519 sizeof(args), &ret, sizeof(ret));
521 /* XXX we're betting rc == PTL_OK here */
522 PORTAL_FREE(eq->base, eq->size * sizeof(ptl_event_t));
523 PORTAL_FREE(eq, sizeof(*eq));
528 int PtlACEntry(ptl_handle_ni_t ni_in, ptl_ac_index_t index_in,
529 ptl_process_id_t match_id_in, ptl_pt_index_t portal_in)
536 * Copy arguments into the argument block to
537 * hand to the forwarding object
540 args.index_in = index_in;
541 args.match_id_in = match_id_in;
542 args.portal_in = portal_in;
544 rc = do_forward(ni_in, PTL_ACENTRY, &args, sizeof(args), &ret,
547 return (rc != PTL_OK) ? rc : ret.rc;
550 int PtlPut(ptl_handle_md_t md_in, ptl_ack_req_t ack_req_in,
551 ptl_process_id_t target_in, ptl_pt_index_t portal_in,
552 ptl_ac_index_t cookie_in, ptl_match_bits_t match_bits_in,
553 ptl_size_t offset_in, ptl_hdr_data_t hdr_data_in)
560 * Copy arguments into the argument block to
561 * hand to the forwarding object
564 args.ack_req_in = ack_req_in;
565 args.target_in = target_in;
566 args.portal_in = portal_in;
567 args.cookie_in = cookie_in;
568 args.match_bits_in = match_bits_in;
569 args.offset_in = offset_in;
570 args.hdr_data_in = hdr_data_in;
572 rc = do_forward(md_in, PTL_PUT, &args, sizeof(args), &ret, sizeof(ret));
574 return (rc != PTL_OK) ? rc : ret.rc;
577 int PtlGet(ptl_handle_md_t md_in, ptl_process_id_t target_in,
578 ptl_pt_index_t portal_in, ptl_ac_index_t cookie_in,
579 ptl_match_bits_t match_bits_in, ptl_size_t offset_in)
586 * Copy arguments into the argument block to
587 * hand to the forwarding object
590 args.target_in = target_in;
591 args.portal_in = portal_in;
592 args.cookie_in = cookie_in;
593 args.match_bits_in = match_bits_in;
594 args.offset_in = offset_in;
596 rc = do_forward(md_in, PTL_GET, &args, sizeof(args), &ret, sizeof(ret));
598 return (rc != PTL_OK) ? rc : ret.rc;