Whamcloud - gitweb
land v0.9.1 on HEAD, in preparation for a 1.0.x branch
[fs/lustre-release.git] / lnet / lnet / lib-me.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * lib/lib-me.c
5  * Match Entry management routines
6  *
7  *  Copyright (c) 2001-2003 Cluster File Systems, Inc.
8  *  Copyright (c) 2001-2002 Sandia National Laboratories
9  *
10  *   This file is part of Lustre, http://www.sf.net/projects/lustre/
11  *
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.
15  *
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.
20  *
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.
24  */
25
26 #ifndef __KERNEL__
27 # include <stdio.h>
28 #else
29 # define DEBUG_SUBSYSTEM S_PORTALS
30 # include <linux/kp30.h>
31 #endif
32
33 #include <portals/lib-p30.h>
34 #include <portals/arg-blocks.h>
35
36 static void lib_me_dump(nal_cb_t * nal, lib_me_t * me);
37
38 int do_PtlMEAttach(nal_cb_t * nal, void *private, void *v_args, void *v_ret)
39 {
40         PtlMEAttach_in *args = v_args;
41         PtlMEAttach_out *ret = v_ret;
42         lib_ni_t *ni = &nal->ni;
43         lib_ptl_t *tbl = &ni->tbl;
44         unsigned long flags;
45         lib_me_t *me;
46
47         if (args->index_in >= tbl->size)
48                 return ret->rc = PTL_INV_PTINDEX;
49
50         /* Should check for valid matchid, but not yet */
51         if (0)
52                 return ret->rc = PTL_INV_PROC;
53
54         me = lib_me_alloc (nal);
55         if (me == NULL)
56                 return (ret->rc = PTL_NOSPACE);
57
58         state_lock(nal, &flags);
59
60         me->match_id = args->match_id_in;
61         me->match_bits = args->match_bits_in;
62         me->ignore_bits = args->ignore_bits_in;
63         me->unlink = args->unlink_in;
64         me->md = NULL;
65
66         lib_initialise_handle (nal, &me->me_lh, PTL_COOKIE_TYPE_ME);
67
68         if (args->position_in == PTL_INS_AFTER)
69                 list_add_tail(&me->me_list, &(tbl->tbl[args->index_in]));
70         else
71                 list_add(&me->me_list, &(tbl->tbl[args->index_in]));
72
73         ptl_me2handle(&ret->handle_out, me);
74
75         state_unlock(nal, &flags);
76
77         return ret->rc = PTL_OK;
78 }
79
80 int do_PtlMEInsert(nal_cb_t * nal, void *private, void *v_args, void *v_ret)
81 {
82         PtlMEInsert_in *args = v_args;
83         PtlMEInsert_out *ret = v_ret;
84         unsigned long flags;
85         lib_me_t *me;
86         lib_me_t *new;
87
88         new = lib_me_alloc (nal);
89         if (new == NULL)
90                 return (ret->rc = PTL_NOSPACE);
91
92         /* Should check for valid matchid, but not yet */
93
94         state_lock(nal, &flags);
95
96         me = ptl_handle2me(&args->current_in, nal);
97         if (me == NULL) {
98                 lib_me_free (nal, new);
99
100                 state_unlock (nal, &flags);
101                 return (ret->rc = PTL_INV_ME);
102         }
103
104         new->match_id = args->match_id_in;
105         new->match_bits = args->match_bits_in;
106         new->ignore_bits = args->ignore_bits_in;
107         new->unlink = args->unlink_in;
108         new->md = NULL;
109
110         lib_initialise_handle (nal, &new->me_lh, PTL_COOKIE_TYPE_ME);
111
112         if (args->position_in == PTL_INS_AFTER)
113                 list_add_tail(&new->me_list, &me->me_list);
114         else
115                 list_add(&new->me_list, &me->me_list);
116
117         ptl_me2handle(&ret->handle_out, new);
118
119         state_unlock(nal, &flags);
120
121         return ret->rc = PTL_OK;
122 }
123
124 int do_PtlMEUnlink(nal_cb_t * nal, void *private, void *v_args, void *v_ret)
125 {
126         PtlMEUnlink_in *args = v_args;
127         PtlMEUnlink_out *ret = v_ret;
128         unsigned long flags;
129         lib_me_t *me;
130
131         state_lock(nal, &flags);
132
133         me = ptl_handle2me(&args->current_in, nal);
134         if (me == NULL) {
135                 ret->rc = PTL_INV_ME;
136         } else {
137                 lib_me_unlink(nal, me);
138                 ret->rc = PTL_OK;
139         }
140
141         state_unlock(nal, &flags);
142
143         return (ret->rc);
144 }
145
146 /* call with state_lock please */
147 void lib_me_unlink(nal_cb_t *nal, lib_me_t *me)
148 {
149         lib_ni_t *ni = &nal->ni;
150
151         if (ni->debug & PTL_DEBUG_UNLINK) {
152                 ptl_handle_any_t handle;
153                 ptl_me2handle(&handle, me);
154         }
155
156         list_del (&me->me_list);
157
158         if (me->md) {
159                 me->md->me = NULL;
160                 lib_md_unlink(nal, me->md);
161         }
162
163         lib_invalidate_handle (nal, &me->me_lh);
164         lib_me_free(nal, me);
165 }
166
167 int do_PtlTblDump(nal_cb_t * nal, void *private, void *v_args, void *v_ret)
168 {
169         PtlTblDump_in *args = v_args;
170         PtlTblDump_out *ret = v_ret;
171         lib_ptl_t *tbl = &nal->ni.tbl;
172         ptl_handle_any_t handle;
173         struct list_head *tmp;
174         unsigned long flags;
175
176         if (args->index_in < 0 || args->index_in >= tbl->size)
177                 return ret->rc = PTL_INV_PTINDEX;
178
179         nal->cb_printf(nal, "Portal table index %d\n", args->index_in);
180
181         state_lock(nal, &flags);
182         list_for_each(tmp, &(tbl->tbl[args->index_in])) {
183                 lib_me_t *me = list_entry(tmp, lib_me_t, me_list);
184                 ptl_me2handle(&handle, me);
185                 lib_me_dump(nal, me);
186         }
187         state_unlock(nal, &flags);
188
189         return ret->rc = PTL_OK;
190 }
191
192 int do_PtlMEDump(nal_cb_t * nal, void *private, void *v_args, void *v_ret)
193 {
194         PtlMEDump_in *args = v_args;
195         PtlMEDump_out *ret = v_ret;
196         lib_me_t *me;
197         unsigned long flags;
198
199         state_lock(nal, &flags);
200
201         me = ptl_handle2me(&args->current_in, nal);
202         if (me == NULL) {
203                 ret->rc = PTL_INV_ME;
204         } else {
205                 lib_me_dump(nal, me);
206                 ret->rc = PTL_OK;
207         }
208
209         state_unlock(nal, &flags);
210
211         return ret->rc;
212 }
213
214 static void lib_me_dump(nal_cb_t * nal, lib_me_t * me)
215 {
216         nal->cb_printf(nal, "Match Entry %p ("LPX64")\n", me, 
217                        me->me_lh.lh_cookie);
218
219         nal->cb_printf(nal, "\tMatch/Ignore\t= %016lx / %016lx\n",
220                        me->match_bits, me->ignore_bits);
221
222         nal->cb_printf(nal, "\tMD\t= %p\n", me->md);
223         nal->cb_printf(nal, "\tprev\t= %p\n",
224                        list_entry(me->me_list.prev, lib_me_t, me_list));
225         nal->cb_printf(nal, "\tnext\t= %p\n",
226                        list_entry(me->me_list.next, lib_me_t, me_list));
227 }