Whamcloud - gitweb
* Landed portals:b_port_step as follows...
[fs/lustre-release.git] / lnet / include / libcfs / kp30.h
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  */
4 #ifndef __LIBCFS_KP30_H__
5 #define __LIBCFS_KP30_H__
6
7 #define PORTAL_DEBUG
8 #include <libcfs/libcfs.h>
9
10 #include <libcfs/arch/kp30.h>
11
12 #ifdef __KERNEL__
13
14 # ifndef DEBUG_SUBSYSTEM
15 #  define DEBUG_SUBSYSTEM S_UNDEFINED
16 # endif
17
18 #ifdef PORTAL_DEBUG
19 extern void kportal_assertion_failed(char *expr, char *file, const char *func,
20                                      const int line);
21 #define LASSERT(e) ((e) ? 0 : kportal_assertion_failed( #e , __FILE__,  \
22                                                         __FUNCTION__, __LINE__))
23 #define LASSERTF(cond, fmt...)                                                \
24         do {                                                                  \
25                 if (unlikely(!(cond))) {                                      \
26                         portals_debug_msg(DEBUG_SUBSYSTEM, D_EMERG,  __FILE__,\
27                                           __FUNCTION__,__LINE__, CDEBUG_STACK,\
28                                           "ASSERTION(" #cond ") failed:" fmt);\
29                         LBUG();                                               \
30                 }                                                             \
31         } while (0)
32
33 #else
34 #define LASSERT(e)
35 #define LASSERTF(cond, fmt...) do { } while (0)
36 #endif
37
38 /* LBUG_WITH_LOC defined in portals/<os>/kp30.h */
39 #define LBUG() LBUG_WITH_LOC(__FILE__, __FUNCTION__, __LINE__)
40
41 /*
42  * Memory
43  */
44 #ifdef PORTAL_DEBUG
45 extern atomic_t portal_kmemory;
46
47 # define portal_kmem_inc(ptr, size)                                           \
48 do {                                                                          \
49         atomic_add(size, &portal_kmemory);                                    \
50 } while (0)
51
52 # define portal_kmem_dec(ptr, size) do {                                      \
53         atomic_sub(size, &portal_kmemory);                                    \
54 } while (0)
55
56 #else
57 # define portal_kmem_inc(ptr, size) do {} while (0)
58 # define portal_kmem_dec(ptr, size) do {} while (0)
59 #endif /* PORTAL_DEBUG */
60
61 #define PORTAL_VMALLOC_SIZE        16384
62
63 #define PORTAL_ALLOC_GFP(ptr, size, mask)                                 \
64 do {                                                                      \
65         LASSERT(!in_interrupt() ||                                        \
66                (size <= PORTAL_VMALLOC_SIZE && mask == CFS_ALLOC_ATOMIC));\
67         if ((size) > PORTAL_VMALLOC_SIZE)                                 \
68                 (ptr) = cfs_alloc_large(size);                            \
69         else                                                              \
70                 (ptr) = cfs_alloc((size), (mask));                        \
71         if ((ptr) == NULL) {                                              \
72                 CERROR("PORTALS: out of memory at %s:%d (tried to alloc '"\
73                        #ptr "' = %d)\n", __FILE__, __LINE__, (int)(size));\
74                 CERROR("PORTALS: %d total bytes allocated by portals\n",  \
75                        atomic_read(&portal_kmemory));                     \
76         } else {                                                          \
77                 portal_kmem_inc((ptr), (size));                           \
78                 if (!((mask) & CFS_ALLOC_ZERO))                           \
79                        memset((ptr), 0, (size));                          \
80         }                                                                 \
81         CDEBUG(D_MALLOC, "kmalloced '" #ptr "': %d at %p (tot %d).\n",    \
82                (int)(size), (ptr), atomic_read (&portal_kmemory));        \
83 } while (0)
84
85 #define PORTAL_ALLOC(ptr, size) \
86         PORTAL_ALLOC_GFP(ptr, size, CFS_ALLOC_IO)
87
88 #define PORTAL_ALLOC_ATOMIC(ptr, size) \
89         PORTAL_ALLOC_GFP(ptr, size, CFS_ALLOC_ATOMIC)
90
91 #define PORTAL_FREE(ptr, size)                                          \
92 do {                                                                    \
93         int s = (size);                                                 \
94         if ((ptr) == NULL) {                                            \
95                 CERROR("PORTALS: free NULL '" #ptr "' (%d bytes) at "   \
96                        "%s:%d\n", s, __FILE__, __LINE__);               \
97                 break;                                                  \
98         }                                                               \
99         if (s > PORTAL_VMALLOC_SIZE)                                    \
100                 cfs_free_large(ptr);                                    \
101         else                                                            \
102                 cfs_free(ptr);                                          \
103         portal_kmem_dec((ptr), s);                                      \
104         CDEBUG(D_MALLOC, "kfreed '" #ptr "': %d at %p (tot %d).\n",     \
105                s, (ptr), atomic_read(&portal_kmemory));                 \
106 } while (0)
107
108 /******************************************************************************/
109
110 #ifdef PORTALS_PROFILING
111 #define prof_enum(FOO) PROF__##FOO
112 enum {
113         prof_enum(our_recvmsg),
114         prof_enum(our_sendmsg),
115         prof_enum(socknal_recv),
116         prof_enum(lib_parse),
117         prof_enum(conn_list_walk),
118         prof_enum(memcpy),
119         prof_enum(lib_finalize),
120         prof_enum(pingcli_time),
121         prof_enum(gmnal_send),
122         prof_enum(gmnal_recv),
123         MAX_PROFS
124 };
125
126 struct prof_ent {
127         char *str;
128         /* hrmph.  wrap-tastic. */
129         u32       starts;
130         u32       finishes;
131         cycles_t  total_cycles;
132         cycles_t  start;
133         cycles_t  end;
134 };
135
136 extern struct prof_ent prof_ents[MAX_PROFS];
137
138 #define PROF_START(FOO)                                         \
139         do {                                                    \
140                 struct prof_ent *pe = &prof_ents[PROF__##FOO];  \
141                 pe->starts++;                                   \
142                 pe->start = get_cycles();                       \
143         } while (0)
144
145 #define PROF_FINISH(FOO)                                        \
146         do {                                                    \
147                 struct prof_ent *pe = &prof_ents[PROF__##FOO];  \
148                 pe->finishes++;                                 \
149                 pe->end = get_cycles();                         \
150                 pe->total_cycles += (pe->end - pe->start);      \
151         } while (0)
152 #else /* !PORTALS_PROFILING */
153 #define PROF_START(FOO) do {} while(0)
154 #define PROF_FINISH(FOO) do {} while(0)
155 #endif /* PORTALS_PROFILING */
156
157 /* debug.c */
158 extern spinlock_t stack_backtrace_lock;
159
160 void portals_debug_dumpstack(cfs_task_t *tsk);
161 void portals_run_upcall(char **argv);
162 void portals_run_lbug_upcall(char * file, const char *fn, const int line);
163 void portals_debug_dumplog(void);
164 int portals_debug_init(unsigned long bufsize);
165 int portals_debug_cleanup(void);
166 int portals_debug_clear_buffer(void);
167 int portals_debug_mark_buffer(char *text);
168 int portals_debug_set_daemon(unsigned int cmd, unsigned int length,
169                              char *file, unsigned int size);
170 __s32 portals_debug_copy_to_user(char *buf, unsigned long len);
171 /* Use the special GNU C __attribute__ hack to have the compiler check the
172  * printf style argument string against the actual argument count and
173  * types.
174  */
175 void portals_debug_msg(int subsys, int mask, char *file, const char *fn,
176                        const int line, unsigned long stack,
177                        char *format, ...)
178         __attribute__ ((format (printf, 7, 8)));
179 void portals_debug_set_level(unsigned int debug_level);
180
181 extern void kportal_daemonize (char *name);
182 extern void kportal_blockallsigs (void);
183
184 #else  /* !__KERNEL__ */
185 # ifndef DEBUG_SUBSYSTEM
186 #  define DEBUG_SUBSYSTEM S_UNDEFINED
187 # endif
188 # ifdef PORTAL_DEBUG
189 #  undef NDEBUG
190 #  include <assert.h>
191 #  define LASSERT(e)     assert(e)
192 #  define LASSERTF(cond, args...)                                              \
193 do {                                                                           \
194           if (!(cond))                                                         \
195                 CERROR(args);                                                  \
196           assert(cond);                                                        \
197 } while (0)
198 # else
199 #  define LASSERT(e)
200 #  define LASSERTF(cond, args...) do { } while (0)
201 # endif
202 # define printk(format, args...) printf (format, ## args)
203 # define PORTAL_ALLOC(ptr, size) do { (ptr) = malloc(size); } while (0);
204 # define PORTAL_FREE(a, b) do { free(a); } while (0);
205 void portals_debug_dumplog(void);
206 # define portals_debug_msg(subsys, mask, file, fn, line, stack, format, a...) \
207     printf("%02x:%06x (@%lu %s:%s,l. %d %d %lu): " format,                    \
208            (subsys), (mask), (long)time(0), file, fn, line,                   \
209            getpid() , stack, ## a);
210
211 #undef CWARN
212 #undef CERROR
213 #define CWARN(format, a...) CDEBUG(D_WARNING, format, ## a)
214 #define CERROR(format, a...) CDEBUG(D_ERROR, format, ## a)
215 #endif
216
217 /*
218  * compile-time assertions. @cond has to be constant expression.
219  * ISO C Standard:
220  *
221  *        6.8.4.2  The switch statement
222  *
223  *       ....
224  *
225  *       [#3] The expression of each case label shall be  an  integer
226  *       constant   expression  and  no  two  of  the  case  constant
227  *       expressions in the same switch statement shall have the same
228  *       value  after  conversion...
229  *
230  */
231 #define CLASSERT(cond) ({ switch(42) { case (cond): case 0: break; } })
232
233 /* support decl needed both by kernel and liblustre */
234 char *portals_nid2str(int nal, ptl_nid_t nid, char *str);
235 char *portals_id2str(int nal, ptl_process_id_t nid, char *str);
236
237 #ifndef CURRENT_TIME
238 # define CURRENT_TIME time(0)
239 #endif
240
241 /* --------------------------------------------------------------------
242  * Light-weight trace
243  * Support for temporary event tracing with minimal Heisenberg effect.
244  * All stuff about lwt are put in arch/kp30.h
245  * -------------------------------------------------------------------- */
246
247 struct portals_device_userstate
248 {
249         int          pdu_memhog_pages;
250         cfs_page_t   *pdu_memhog_root_page;
251 };
252
253 #include <libcfs/portals_lib.h>
254
255 /*
256  * USER LEVEL STUFF BELOW
257  */
258
259 #define PORTAL_IOCTL_VERSION 0x00010007
260 #define PING_SYNC       0
261 #define PING_ASYNC      1
262
263 struct portal_ioctl_hdr {
264         __u32 ioc_len;
265         __u32 ioc_version;
266 };
267
268 struct portals_debug_ioctl_data
269 {
270         struct portal_ioctl_hdr hdr;
271         unsigned int subs;
272         unsigned int debug;
273 };
274
275 #define PORTAL_IOC_INIT(data)                           \
276 do {                                                    \
277         memset(&data, 0, sizeof(data));                 \
278         data.ioc_version = PORTAL_IOCTL_VERSION;        \
279         data.ioc_len = sizeof(data);                    \
280 } while (0)
281
282 /* FIXME check conflict with lustre_lib.h */
283 #define PTL_IOC_DEBUG_MASK             _IOWR('f', 250, long)
284
285 static inline int portal_ioctl_packlen(struct portal_ioctl_data *data)
286 {
287         int len = sizeof(*data);
288         len += size_round(data->ioc_inllen1);
289         len += size_round(data->ioc_inllen2);
290         return len;
291 }
292
293 static inline int portal_ioctl_is_invalid(struct portal_ioctl_data *data)
294 {
295         if (data->ioc_len > (1<<30)) {
296                 CERROR ("PORTALS ioctl: ioc_len larger than 1<<30\n");
297                 return 1;
298         }
299         if (data->ioc_inllen1 > (1<<30)) {
300                 CERROR ("PORTALS ioctl: ioc_inllen1 larger than 1<<30\n");
301                 return 1;
302         }
303         if (data->ioc_inllen2 > (1<<30)) {
304                 CERROR ("PORTALS ioctl: ioc_inllen2 larger than 1<<30\n");
305                 return 1;
306         }
307         if (data->ioc_inlbuf1 && !data->ioc_inllen1) {
308                 CERROR ("PORTALS ioctl: inlbuf1 pointer but 0 length\n");
309                 return 1;
310         }
311         if (data->ioc_inlbuf2 && !data->ioc_inllen2) {
312                 CERROR ("PORTALS ioctl: inlbuf2 pointer but 0 length\n");
313                 return 1;
314         }
315         if (data->ioc_pbuf1 && !data->ioc_plen1) {
316                 CERROR ("PORTALS ioctl: pbuf1 pointer but 0 length\n");
317                 return 1;
318         }
319         if (data->ioc_pbuf2 && !data->ioc_plen2) {
320                 CERROR ("PORTALS ioctl: pbuf2 pointer but 0 length\n");
321                 return 1;
322         }
323         if (data->ioc_plen1 && !data->ioc_pbuf1) {
324                 CERROR ("PORTALS ioctl: plen1 nonzero but no pbuf1 pointer\n");
325                 return 1;
326         }
327         if (data->ioc_plen2 && !data->ioc_pbuf2) {
328                 CERROR ("PORTALS ioctl: plen2 nonzero but no pbuf2 pointer\n");
329                 return 1;
330         }
331         if (portal_ioctl_packlen(data) != data->ioc_len ) {
332                 CERROR ("PORTALS ioctl: packlen != ioc_len\n");
333                 return 1;
334         }
335         if (data->ioc_inllen1 &&
336             data->ioc_bulk[data->ioc_inllen1 - 1] != '\0') {
337                 CERROR ("PORTALS ioctl: inlbuf1 not 0 terminated\n");
338                 return 1;
339         }
340         if (data->ioc_inllen2 &&
341             data->ioc_bulk[size_round(data->ioc_inllen1) +
342                            data->ioc_inllen2 - 1] != '\0') {
343                 CERROR ("PORTALS ioctl: inlbuf2 not 0 terminated\n");
344                 return 1;
345         }
346         return 0;
347 }
348
349 #ifndef __KERNEL__
350 static inline int portal_ioctl_pack(struct portal_ioctl_data *data, char **pbuf,
351                                     int max)
352 {
353         char *ptr;
354         struct portal_ioctl_data *overlay;
355         data->ioc_len = portal_ioctl_packlen(data);
356         data->ioc_version = PORTAL_IOCTL_VERSION;
357
358         if (*pbuf && portal_ioctl_packlen(data) > max)
359                 return 1;
360         if (*pbuf == NULL) {
361                 *pbuf = malloc(data->ioc_len);
362         }
363         if (!*pbuf)
364                 return 1;
365         overlay = (struct portal_ioctl_data *)*pbuf;
366         memcpy(*pbuf, data, sizeof(*data));
367
368         ptr = overlay->ioc_bulk;
369         if (data->ioc_inlbuf1)
370                 LOGL(data->ioc_inlbuf1, data->ioc_inllen1, ptr);
371         if (data->ioc_inlbuf2)
372                 LOGL(data->ioc_inlbuf2, data->ioc_inllen2, ptr);
373         if (portal_ioctl_is_invalid(overlay))
374                 return 1;
375
376         return 0;
377 }
378
379 #else
380
381 extern inline int portal_ioctl_getdata(char *buf, char *end, void *arg);
382
383 #endif
384
385 /* ioctls for manipulating snapshots 30- */
386 #define IOC_PORTAL_TYPE                   'e'
387 #define IOC_PORTAL_MIN_NR                 30
388
389 #define IOC_PORTAL_PING                    _IOWR('e', 30, IOCTL_PORTAL_TYPE)
390
391 #define IOC_PORTAL_CLEAR_DEBUG             _IOWR('e', 32, IOCTL_PORTAL_TYPE)
392 #define IOC_PORTAL_MARK_DEBUG              _IOWR('e', 33, IOCTL_PORTAL_TYPE)
393 #define IOC_PORTAL_PANIC                   _IOWR('e', 34, IOCTL_PORTAL_TYPE)
394 #define IOC_PORTAL_NAL_CMD                 _IOWR('e', 35, IOCTL_PORTAL_TYPE)
395 #define IOC_PORTAL_GET_NID                 _IOWR('e', 36, IOCTL_PORTAL_TYPE)
396 #define IOC_PORTAL_FAIL_NID                _IOWR('e', 37, IOCTL_PORTAL_TYPE)
397
398 #define IOC_PORTAL_LWT_CONTROL             _IOWR('e', 39, IOCTL_PORTAL_TYPE)
399 #define IOC_PORTAL_LWT_SNAPSHOT            _IOWR('e', 40, IOCTL_PORTAL_TYPE)
400 #define IOC_PORTAL_LWT_LOOKUP_STRING       _IOWR('e', 41, IOCTL_PORTAL_TYPE)
401 #define IOC_PORTAL_MEMHOG                  _IOWR('e', 42, IOCTL_PORTAL_TYPE)
402 #define IOC_PORTAL_MAX_NR                             42
403
404 enum {
405         QSWNAL    = 1,
406         SOCKNAL   = 2,
407         GMNAL     = 3,
408         /*          4 unused */
409         TCPNAL    = 5,
410         ROUTER    = 6,
411         OPENIBNAL = 7,
412         IIBNAL    = 8,
413         LONAL     = 9,
414         RANAL     = 10,
415         VIBNAL    = 11,
416         NAL_ENUM_END_MARKER
417 };
418
419 #define PTL_NALFMT_SIZE             32 /* %u:%u.%u.%u.%u,%u (10+4+4+4+3+5+1) */
420
421 #define NAL_MAX_NR (NAL_ENUM_END_MARKER - 1)
422
423 #define NAL_CMD_REGISTER_PEER_FD     100
424 #define NAL_CMD_CLOSE_CONNECTION     101
425 #define NAL_CMD_REGISTER_MYNID       102
426 #define NAL_CMD_PUSH_CONNECTION      103
427 #define NAL_CMD_GET_CONN             104
428 #define NAL_CMD_DEL_PEER             105
429 #define NAL_CMD_ADD_PEER             106
430 #define NAL_CMD_GET_PEER             107
431 #define NAL_CMD_GET_TXDESC           108
432 #define NAL_CMD_ADD_ROUTE            109
433 #define NAL_CMD_DEL_ROUTE            110
434 #define NAL_CMD_GET_ROUTE            111
435 #define NAL_CMD_NOTIFY_ROUTER        112
436 #define NAL_CMD_ADD_INTERFACE        113
437 #define NAL_CMD_DEL_INTERFACE        114
438 #define NAL_CMD_GET_INTERFACE        115
439
440
441 enum {
442         DEBUG_DAEMON_START       =  1,
443         DEBUG_DAEMON_STOP        =  2,
444         DEBUG_DAEMON_PAUSE       =  3,
445         DEBUG_DAEMON_CONTINUE    =  4,
446 };
447
448
449 enum cfg_record_type {
450         PORTALS_CFG_TYPE = 1,
451         LUSTRE_CFG_TYPE = 123,
452 };
453
454 typedef int (*cfg_record_cb_t)(enum cfg_record_type, int len, void *data);
455
456 /* lustre_id output helper macros */
457 #define DLID4   "%lu/%lu/%lu/%lu"
458
459 #define OLID4(id)                              \
460     (unsigned long)(id)->li_fid.lf_id,         \
461     (unsigned long)(id)->li_fid.lf_group,      \
462     (unsigned long)(id)->li_stc.u.e3s.l3s_ino, \
463     (unsigned long)(id)->li_stc.u.e3s.l3s_gen
464
465 #endif